agentengine-sdk-python 0.8.5__py3-none-any.whl → 0.8.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/METADATA +12 -8
- {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/RECORD +823 -388
- ksadk/_async_iterators.py +79 -0
- ksadk/_build_provenance.json +1 -1
- ksadk/_model_anthropic.py +49 -0
- ksadk/_model_input.py +86 -0
- ksadk/_model_json.py +40 -0
- ksadk/_model_reasoning.py +17 -0
- ksadk/_model_refusal.py +20 -0
- ksadk/_model_sse.py +163 -0
- ksadk/a2a/__init__.py +157 -167
- ksadk/a2a/_invocation_state.py +86 -0
- ksadk/a2a/_space_client_events.py +33 -22
- ksadk/a2a/adk.py +194 -0
- ksadk/a2a/adk_invocation_context.py +242 -0
- ksadk/a2a/adk_runtime.py +126 -0
- ksadk/a2a/adk_tools.py +319 -0
- ksadk/a2a/bootstrap.py +149 -23
- ksadk/a2a/build_validation.py +147 -0
- ksadk/a2a/card.py +23 -15
- ksadk/a2a/codex.py +160 -0
- ksadk/a2a/codex_checkpoint.py +111 -0
- ksadk/a2a/codex_recovery.py +96 -0
- ksadk/a2a/codex_recovery_events.py +123 -0
- ksadk/a2a/codex_runtime.py +198 -0
- ksadk/a2a/codex_session_checkpoint.py +162 -0
- ksadk/a2a/composition.py +88 -0
- ksadk/a2a/context_store.py +118 -19
- ksadk/a2a/control_plane.py +108 -106
- ksadk/a2a/event_adapter.py +92 -193
- ksadk/a2a/executor.py +257 -85
- ksadk/a2a/exposure.py +106 -0
- ksadk/a2a/external_transport.py +3 -4
- ksadk/a2a/identity.py +106 -12
- ksadk/a2a/ids.py +14 -3
- ksadk/a2a/inbound_kernel.py +133 -0
- ksadk/a2a/interaction_wire.py +76 -0
- ksadk/a2a/invocation_checkpoint.py +274 -0
- ksadk/a2a/invocation_policy.py +87 -0
- ksadk/a2a/invocation_publication.py +210 -0
- ksadk/a2a/invocation_service.py +972 -0
- ksadk/a2a/invocation_types.py +459 -0
- ksadk/a2a/kernel_task_adapter.py +259 -0
- ksadk/a2a/langgraph.py +20 -7
- ksadk/a2a/langgraph_invocation_context.py +136 -0
- ksadk/a2a/langgraph_managed.py +150 -0
- ksadk/a2a/langgraph_recovery.py +32 -0
- ksadk/a2a/langgraph_runtime.py +89 -0
- ksadk/a2a/langgraph_tool_runtime.py +132 -0
- ksadk/a2a/langgraph_tools.py +63 -0
- ksadk/a2a/message_digest.py +40 -0
- ksadk/a2a/platform.py +389 -0
- ksadk/a2a/policy_refs.py +13 -0
- ksadk/a2a/presentation.py +402 -0
- ksadk/a2a/product_kernel_facts.py +177 -0
- ksadk/a2a/product_key.py +99 -0
- ksadk/a2a/protocol_errors.py +116 -0
- ksadk/a2a/result_text.py +49 -0
- ksadk/a2a/resume_store.py +93 -3
- ksadk/a2a/routes.py +6 -1
- ksadk/a2a/runtime_approval.py +198 -0
- ksadk/a2a/runtime_input.py +151 -0
- ksadk/a2a/server.py +16 -7
- ksadk/a2a/space_client.py +101 -16
- ksadk/a2a/task_adapter.py +19 -5
- ksadk/a2a/task_event_dispatcher.py +39 -2
- ksadk/a2a/task_event_outbox.py +215 -0
- ksadk/a2a/task_event_outbox_owned.py +130 -0
- ksadk/a2a/task_store.py +37 -0
- ksadk/a2a/tool_activity.py +176 -0
- ksadk/a2a/workload_tokens.py +134 -0
- ksadk/api/client.py +32 -79
- ksadk/api/sse_stream.py +96 -0
- ksadk/builders/code_builder.py +83 -106
- ksadk/builders/container_builder.py +11 -29
- ksadk/builders/framework_requirements.py +2 -0
- ksadk/builders/managed_runtime_builder.py +12 -0
- ksadk/builders/source_provenance.py +87 -0
- ksadk/cli/cmd_a2a.py +43 -0
- ksadk/cli/cmd_build.py +9 -0
- ksadk/cli/cmd_deploy.py +27 -2
- ksadk/cli/cmd_invoke.py +45 -92
- ksadk/cli/cmd_studio.py +5 -1
- ksadk/cli/cmd_web.py +2 -0
- ksadk/cli/hosted_invoke.py +206 -0
- ksadk/cli/invoke_content.py +60 -0
- ksadk/cli/runtime_bootstrap.py +27 -5
- ksadk/codex/_expert_request_reader.py +48 -0
- ksadk/codex/a2a_tools.py +140 -0
- ksadk/codex/async_approval.py +169 -0
- ksadk/codex/async_client.py +938 -0
- ksadk/codex/async_proxy.py +216 -0
- ksadk/codex/base_runtime.py +25 -0
- ksadk/codex/client.py +3 -1048
- ksadk/codex/client_payloads.py +85 -0
- ksadk/codex/rollout_checkpoint.py +264 -0
- ksadk/codex/runtime.py +290 -54
- ksadk/common/auth.py +2 -2
- ksadk/common/cloud_headers.py +36 -0
- ksadk/common/diagnostics.py +34 -0
- ksadk/common/kop_client.py +2 -1
- ksadk/configs/env_registry.py +106 -127
- ksadk/configs/env_registry_a2a.py +173 -0
- ksadk/configs/env_registry_studio.py +53 -5
- ksadk/configs/global_config.py +1 -0
- ksadk/configs/settings.py +6 -0
- ksadk/context_engine/assembler.py +9 -0
- ksadk/context_engine/contributors.py +80 -17
- ksadk/context_engine/instruction_authority.py +18 -0
- ksadk/conversations/attachments.py +53 -15
- ksadk/conversations/contracts.py +28 -9
- ksadk/conversations/message_projection.py +30 -125
- ksadk/conversations/message_projection_blocks.py +137 -0
- ksadk/conversations/model_context.py +11 -3
- ksadk/conversations/projector.py +63 -0
- ksadk/conversations/runtime_compaction.py +7 -2
- ksadk/conversations/runtime_input.py +16 -4
- ksadk/conversations/runtime_payloads.py +4 -0
- ksadk/conversations/runtime_persistence.py +192 -24
- ksadk/conversations/runtime_preparation.py +85 -6
- ksadk/conversations/runtime_projection.py +217 -0
- ksadk/conversations/runtime_resume.py +141 -70
- ksadk/conversations/tool_receipt_resume.py +387 -0
- ksadk/conversations/tool_receipts.py +32 -0
- ksadk/deployment/env_forward.py +5 -0
- ksadk/deployment/manager.py +15 -6
- ksadk/deployment/providers/serverless.py +76 -136
- ksadk/deployment/providers/serverless_payloads.py +122 -0
- ksadk/evaluation/agent_eval_client.py +2 -1
- ksadk/evaluation/contracts.py +78 -3
- ksadk/evaluation/evaluators.py +166 -1
- ksadk/evaluation/evidence.py +271 -4
- ksadk/evaluation/local_adapter.py +76 -12
- ksadk/evaluation/studio_build_adapter.py +73 -9
- ksadk/events/adapters/_a2a_checkpoint.py +151 -0
- ksadk/events/adapters/_a2a_snapshot.py +18 -14
- ksadk/events/adapters/_a2a_support.py +15 -3
- ksadk/events/adapters/_a2a_tool_activity.py +123 -0
- ksadk/events/adapters/_codex_errors.py +49 -0
- ksadk/events/adapters/_langgraph_support.py +12 -1
- ksadk/events/adapters/a2a.py +54 -26
- ksadk/events/adapters/adk.py +188 -30
- ksadk/events/adapters/codex.py +33 -7
- ksadk/events/adapters/langgraph.py +16 -6
- ksadk/events/canonical.py +5 -0
- ksadk/events/canonical_store.py +200 -4
- ksadk/events/reducer.py +82 -0
- ksadk/events/run_authority.py +176 -0
- ksadk/harness/__init__.py +4 -0
- ksadk/harness/artifact_adapters/__init__.py +1 -0
- ksadk/harness/artifact_adapters/native_page_budget.py +172 -0
- ksadk/harness/artifact_adapters/native_search.py +249 -0
- ksadk/harness/artifact_adapters/native_search_budget.py +134 -0
- ksadk/harness/artifact_adapters/native_store.py +115 -0
- ksadk/harness/artifact_adapters/native_tool.py +222 -0
- ksadk/harness/artifact_store.py +26 -9
- ksadk/harness/browser_adapters/__init__.py +6 -0
- ksadk/harness/browser_adapters/native_browser_tool.py +92 -0
- ksadk/harness/browser_adapters/native_dom_snapshot.py +187 -0
- ksadk/harness/browser_adapters/native_playwright.py +953 -0
- ksadk/harness/browser_adapters/native_vision.py +295 -0
- ksadk/harness/capability_adapters/__init__.py +1 -0
- ksadk/harness/capability_adapters/native_dsh.py +289 -0
- ksadk/harness/capability_runtime.py +104 -9
- ksadk/harness/compaction_record.py +31 -0
- ksadk/harness/compiler.py +3 -3
- ksadk/harness/config.py +28 -5
- ksadk/harness/conformance/contract.py +9 -11
- ksadk/harness/context_engine.py +18 -33
- ksadk/harness/context_sections.py +397 -0
- ksadk/harness/diagnostic_adapters/__init__.py +1 -0
- ksadk/harness/diagnostic_adapters/contracts.py +70 -0
- ksadk/harness/diagnostic_adapters/lsp_rpc.py +210 -0
- ksadk/harness/diagnostic_adapters/native_lsp.py +286 -0
- ksadk/harness/engine/completion_guard.py +16 -1
- ksadk/harness/engine/context_pipeline.py +864 -92
- ksadk/harness/engine/graph_builder.py +123 -630
- ksadk/harness/engine/hooked_reasoner.py +380 -0
- ksadk/harness/engine/langgraph.py +126 -8
- ksadk/harness/engine/mcp_disclosure.py +65 -114
- ksadk/harness/engine/phases/__init__.py +6 -0
- ksadk/harness/engine/phases/context.py +48 -0
- ksadk/harness/engine/phases/interaction.py +31 -0
- ksadk/harness/engine/phases/reason.py +552 -0
- ksadk/harness/engine/phases/tools.py +638 -0
- ksadk/harness/engine/policy_runtime.py +21 -10
- ksadk/harness/engine/postgres_checkpointer.py +325 -2
- ksadk/harness/engine/run_control_bridge.py +21 -1
- ksadk/harness/engine/run_types.py +10 -0
- ksadk/harness/engine/skill_disclosure.py +98 -12
- ksadk/harness/engine/steering.py +177 -0
- ksadk/harness/engine/subagents.py +18 -1
- ksadk/harness/engine/tool_dispatch.py +112 -7
- ksadk/harness/events.py +39 -2
- ksadk/harness/execution_policy.py +10 -0
- ksadk/harness/hooks.py +259 -0
- ksadk/harness/loop/reason.py +281 -36
- ksadk/harness/loop/tools.py +157 -12
- ksadk/harness/managed_runtime.py +254 -94
- ksadk/harness/mcp_disclosure_contract.py +85 -0
- ksadk/harness/mcp_result_policy.py +44 -0
- ksadk/harness/mcp_runtime.py +33 -0
- ksadk/harness/micro_compact.py +69 -0
- ksadk/harness/model_adapters/__init__.py +1 -0
- ksadk/harness/model_adapters/native_mcp_media.py +100 -0
- ksadk/harness/model_adapters/native_mcp_result.py +36 -0
- ksadk/harness/model_adapters/native_openai.py +703 -0
- ksadk/harness/model_capability.py +223 -8
- ksadk/harness/model_provider.py +214 -4
- ksadk/harness/multimodal.py +57 -0
- ksadk/harness/native/__init__.py +1 -0
- ksadk/harness/native/activation_contract.py +25 -0
- ksadk/harness/native/activation_recovery.py +29 -0
- ksadk/harness/native/adapters.py +291 -0
- ksadk/harness/native/artifact_contract.py +14 -0
- ksadk/harness/native/artifact_partial_read_capacity.py +171 -0
- ksadk/harness/native/artifact_read_capacity.py +182 -0
- ksadk/harness/native/artifact_read_contract.py +27 -0
- ksadk/harness/native/artifact_runtime.py +408 -0
- ksadk/harness/native/artifact_search_capacity.py +206 -0
- ksadk/harness/native/artifact_search_contract.py +40 -0
- ksadk/harness/native/artifact_single_read_capacity.py +170 -0
- ksadk/harness/native/browser_contract.py +229 -0
- ksadk/harness/native/browser_recovery.py +183 -0
- ksadk/harness/native/capabilities.py +204 -0
- ksadk/harness/native/child_approval.py +60 -0
- ksadk/harness/native/child_budget.py +136 -0
- ksadk/harness/native/child_cancellation.py +80 -0
- ksadk/harness/native/child_input.py +98 -0
- ksadk/harness/native/child_input_runtime.py +59 -0
- ksadk/harness/native/child_interruption.py +81 -0
- ksadk/harness/native/child_lifecycle.py +246 -0
- ksadk/harness/native/child_lifecycle_contract.py +91 -0
- ksadk/harness/native/child_notifications.py +75 -0
- ksadk/harness/native/child_promotion.py +66 -0
- ksadk/harness/native/command_runtime.py +99 -0
- ksadk/harness/native/completion.py +302 -0
- ksadk/harness/native/completion_text.py +116 -0
- ksadk/harness/native/context.py +358 -0
- ksadk/harness/native/context_artifact_page.py +75 -0
- ksadk/harness/native/context_compaction_projection.py +131 -0
- ksadk/harness/native/context_contributions.py +320 -0
- ksadk/harness/native/context_contributor_contract.py +133 -0
- ksadk/harness/native/context_driver.py +820 -0
- ksadk/harness/native/context_fresh_tools.py +49 -0
- ksadk/harness/native/context_history.py +272 -0
- ksadk/harness/native/context_microcompact.py +61 -0
- ksadk/harness/native/context_partial_summary.py +58 -0
- ksadk/harness/native/context_partition.py +492 -0
- ksadk/harness/native/context_pruning.py +275 -0
- ksadk/harness/native/context_reduction.py +60 -0
- ksadk/harness/native/context_replay.py +148 -0
- ksadk/harness/native/context_request_projection.py +526 -0
- ksadk/harness/native/context_runtime.py +976 -0
- ksadk/harness/native/context_runtime_contracts.py +409 -0
- ksadk/harness/native/context_search.py +112 -0
- ksadk/harness/native/context_source_fragments.py +188 -0
- ksadk/harness/native/context_source_progress.py +119 -0
- ksadk/harness/native/context_summary_planning.py +788 -0
- ksadk/harness/native/context_summary_recovery.py +105 -0
- ksadk/harness/native/delivery_review.py +331 -0
- ksadk/harness/native/delivery_review_contract.py +54 -0
- ksadk/harness/native/effect_admission.py +82 -0
- ksadk/harness/native/effect_control.py +318 -0
- ksadk/harness/native/effect_receipts.py +729 -0
- ksadk/harness/native/effect_runtime.py +303 -0
- ksadk/harness/native/effective_configuration.py +28 -0
- ksadk/harness/native/engine.py +945 -0
- ksadk/harness/native/final_output.py +34 -0
- ksadk/harness/native/final_submission.py +58 -0
- ksadk/harness/native/finalization_workspace.py +96 -0
- ksadk/harness/native/fork.py +151 -0
- ksadk/harness/native/guidance.py +91 -0
- ksadk/harness/native/history.py +381 -0
- ksadk/harness/native/hook_executor.py +205 -0
- ksadk/harness/native/hook_runtime_contract.py +282 -0
- ksadk/harness/native/interaction_observation.py +117 -0
- ksadk/harness/native/lease.py +103 -0
- ksadk/harness/native/machine.py +974 -0
- ksadk/harness/native/mcp_result_governance.py +156 -0
- ksadk/harness/native/model.py +570 -0
- ksadk/harness/native/model_feedback.py +63 -0
- ksadk/harness/native/model_input.py +30 -0
- ksadk/harness/native/model_recovery_contract.py +35 -0
- ksadk/harness/native/model_replay.py +128 -0
- ksadk/harness/native/model_request.py +133 -0
- ksadk/harness/native/model_runtime.py +196 -0
- ksadk/harness/native/model_takeover.py +419 -0
- ksadk/harness/native/model_tool_batch.py +40 -0
- ksadk/harness/native/observed_progress.py +46 -0
- ksadk/harness/native/operator_guidance.py +201 -0
- ksadk/harness/native/output_contract.py +80 -0
- ksadk/harness/native/output_recovery.py +24 -0
- ksadk/harness/native/ports.py +749 -0
- ksadk/harness/native/precompact_hook_runtime.py +171 -0
- ksadk/harness/native/replay_context.py +149 -0
- ksadk/harness/native/request_media.py +112 -0
- ksadk/harness/native/restore_contract.py +16 -0
- ksadk/harness/native/run_clock.py +120 -0
- ksadk/harness/native/state.py +436 -0
- ksadk/harness/native/steering.py +170 -0
- ksadk/harness/native/stop_hook_runtime.py +151 -0
- ksadk/harness/native/studio_admission.py +29 -0
- ksadk/harness/native/subagents.py +86 -0
- ksadk/harness/native/task_policy.py +99 -0
- ksadk/harness/native/task_progress.py +86 -0
- ksadk/harness/native/terminal_verification.py +43 -0
- ksadk/harness/native/tool_argument_feedback.py +178 -0
- ksadk/harness/native/tool_budget.py +253 -0
- ksadk/harness/native/tool_error_streak.py +89 -0
- ksadk/harness/native/tool_hook_runtime.py +343 -0
- ksadk/harness/native/tool_input_validation.py +58 -0
- ksadk/harness/native/tool_interruption.py +96 -0
- ksadk/harness/native/tool_observation.py +259 -0
- ksadk/harness/native/tool_progress.py +223 -0
- ksadk/harness/native/tool_recovery.py +25 -0
- ksadk/harness/native/tool_scheduling.py +33 -0
- ksadk/harness/native/tool_schema.py +126 -0
- ksadk/harness/native/transitions.py +151 -0
- ksadk/harness/native/turn_control.py +98 -0
- ksadk/harness/native/user_document.py +98 -0
- ksadk/harness/native/user_document_capture.py +49 -0
- ksadk/harness/native/user_input.py +87 -0
- ksadk/harness/native/verification.py +432 -0
- ksadk/harness/native/verification_binding.py +40 -0
- ksadk/harness/native/verification_runtime.py +233 -0
- ksadk/harness/native/verification_workspace.py +67 -0
- ksadk/harness/native_driver_failure.py +123 -0
- ksadk/harness/native_facade.py +977 -0
- ksadk/harness/native_factory.py +244 -0
- ksadk/harness/native_projection.py +503 -0
- ksadk/harness/native_runtime.py +621 -0
- ksadk/harness/native_shadow.py +250 -0
- ksadk/harness/native_shadow_inputs.py +146 -0
- ksadk/harness/progress_adapters/__init__.py +5 -0
- ksadk/harness/progress_adapters/native_todo.py +75 -0
- ksadk/harness/prompt_cache.py +65 -3
- ksadk/harness/public_activity.py +59 -0
- ksadk/harness/public_output.py +30 -0
- ksadk/harness/public_summary.py +36 -0
- ksadk/harness/reasoner.py +331 -22
- ksadk/harness/rpc.py +200 -0
- ksadk/harness/run_control.py +107 -2
- ksadk/harness/runtime.py +11 -2
- ksadk/harness/runtime_capabilities.py +71 -1
- ksadk/harness/sandbox_backend.py +203 -0
- ksadk/harness/sdk.py +153 -0
- ksadk/harness/session_store.py +370 -24
- ksadk/harness/skill_adapters/__init__.py +1 -0
- ksadk/harness/skill_adapters/native_bundle.py +148 -0
- ksadk/harness/skill_adapters/native_disclosure.py +306 -0
- ksadk/harness/skill_intent.py +47 -0
- ksadk/harness/skill_runtime.py +74 -16
- ksadk/harness/spec.py +20 -10
- ksadk/harness/state.py +2 -0
- ksadk/harness/stores/__init__.py +14 -0
- ksadk/harness/stores/native_command_settlement.py +65 -0
- ksadk/harness/stores/native_contract.py +311 -0
- ksadk/harness/stores/native_memory.py +326 -0
- ksadk/harness/stores/native_memory_archive.py +70 -0
- ksadk/harness/stores/native_migration_cli.py +91 -0
- ksadk/harness/stores/native_outbox.py +56 -0
- ksadk/harness/stores/native_sqlite.py +782 -0
- ksadk/harness/stores/native_sqlite_audit.py +29 -0
- ksadk/harness/stores/native_sqlite_migration.py +252 -0
- ksadk/harness/subagent.py +12 -2
- ksadk/harness/subagent_adapters/checkpoint_recovery.py +120 -0
- ksadk/harness/subagent_adapters/native_background_child.py +803 -0
- ksadk/harness/subagent_adapters/native_child.py +819 -0
- ksadk/harness/subagent_adapters/native_child_approval.py +128 -0
- ksadk/harness/subagent_adapters/native_child_continuation.py +51 -0
- ksadk/harness/subagent_adapters/native_child_result.py +392 -0
- ksadk/harness/subagent_adapters/prepared_recovery.py +120 -0
- ksadk/harness/tool_display.py +75 -0
- ksadk/harness/tool_display_contract.py +134 -0
- ksadk/harness/tool_output.py +141 -0
- ksadk/harness/tool_policy.py +3 -0
- ksadk/harness/tool_result_policy.py +216 -0
- ksadk/harness/tools.py +52 -0
- ksadk/harness/workspace_adapters/__init__.py +6 -0
- ksadk/harness/workspace_adapters/native_directory.py +180 -0
- ksadk/harness/workspace_adapters/native_git.py +208 -0
- ksadk/harness/workspace_adapters/native_isolation.py +350 -0
- ksadk/interaction/providers/langgraph.py +8 -1
- ksadk/kernel/bootstrap.py +144 -160
- ksadk/kernel/contract_fingerprints.py +45 -1
- ksadk/kernel/contracts.py +25 -0
- ksadk/kernel/control.py +153 -33
- ksadk/kernel/execution_grants.py +209 -2
- ksadk/kernel/execution_grants_memory.py +127 -8
- ksadk/kernel/execution_grants_postgres.py +188 -10
- ksadk/kernel/execution_grants_sqlite.py +235 -9
- ksadk/kernel/execution_host_ingress.py +1071 -0
- ksadk/kernel/history_projection.py +120 -0
- ksadk/kernel/ingress.py +117 -204
- ksadk/kernel/ingress_bootstrap.py +268 -0
- ksadk/kernel/legacy_history.py +179 -0
- ksadk/kernel/memory_store.py +38 -48
- ksadk/kernel/memory_store_projection.py +63 -0
- ksadk/kernel/postgres_event_log.py +181 -0
- ksadk/kernel/postgres_store.py +167 -198
- ksadk/kernel/readiness.py +125 -0
- ksadk/kernel/recovery.py +89 -3
- ksadk/kernel/recovery_projection.py +124 -0
- ksadk/kernel/runtime_checkpoint.py +34 -0
- ksadk/kernel/sql/001_agent_kernel.sql +5 -0
- ksadk/kernel/sqlite_schema.py +100 -0
- ksadk/kernel/sqlite_store.py +147 -216
- ksadk/kernel/store.py +47 -15
- ksadk/kernel/teams_artifact_tools.py +392 -0
- ksadk/kernel/teams_effects.py +851 -0
- ksadk/kernel/teams_execution_context.py +408 -0
- ksadk/kernel/teams_host_http.py +237 -0
- ksadk/kernel/teams_material_transport.py +245 -0
- ksadk/kernel/teams_materials.py +318 -0
- ksadk/kernel/teams_runtime_bootstrap.py +604 -0
- ksadk/kernel/teams_tool_runtime.py +273 -0
- ksadk/kernel/teams_workspace.py +259 -0
- ksadk/kernel/worker.py +323 -332
- ksadk/kernel/worker_controls.py +454 -0
- ksadk/kernel/worker_identity.py +27 -0
- ksadk/kernel/worker_interactions.py +197 -0
- ksadk/knowledge_base/client.py +15 -1
- ksadk/managed_runtime.py +29 -2
- ksadk/memory/adk/backends/http_ltm_backend.py +2 -1
- ksadk/memory/adk/backends/sdk_ltm_backend.py +15 -1
- ksadk/memory/adk/bounded_database_session_service.py +232 -0
- ksadk/memory/adk/resilient_session_service.py +115 -15
- ksadk/memory/adk/short_term_memory.py +8 -9
- ksadk/memory/extraction.py +120 -7
- ksadk/memory/providers/local_candidates.py +183 -0
- ksadk/memory/providers/local_sqlite.py +252 -78
- ksadk/memory/resolved_policy.py +12 -7
- ksadk/model_gateway/__init__.py +29 -0
- ksadk/model_gateway/client.py +253 -0
- ksadk/model_gateway/events.py +113 -0
- ksadk/model_gateway/matrix.py +297 -0
- ksadk/model_proxy/compat.py +670 -0
- ksadk/model_proxy/server.py +10 -7
- ksadk/model_proxy/transform.py +37 -9
- ksadk/plugins/bridges/dsh.py +18 -20
- ksadk/plugins/bridges/dsh_profile_manifest.py +36 -0
- ksadk/plugins/builtin_resources.py +199 -0
- ksadk/plugins/builtins.py +380 -186
- ksadk/plugins/context_contributor.py +15 -4
- ksadk/plugins/dsh_dependency_policy.py +41 -0
- ksadk/plugins/dsh_toolchain.py +24 -35
- ksadk/plugins/execution_host.py +8 -0
- ksadk/plugins/host.py +73 -5
- ksadk/plugins/kernel_adapter.py +44 -1
- ksadk/plugins/memory_provider.py +180 -0
- ksadk/plugins/providers/_process_group.py +50 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +24 -2
- ksadk/plugins/providers/bundles/dsh-knowledge/package.json +1 -1
- ksadk/plugins/providers/bundles/dsh-memory/package.json +1 -1
- ksadk/plugins/providers/bundles/dsh-skill-center/package.json +1 -1
- ksadk/plugins/providers/bundles/dsh-teams-tools/package.json +1 -1
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +1 -1
- ksadk/plugins/providers/codex.py +42 -38
- ksadk/plugins/providers/codex_native.py +20 -0
- ksadk/plugins/providers/codex_skills.py +46 -0
- ksadk/plugins/providers/dsh_capabilities.py +16 -171
- ksadk/plugins/providers/dsh_connector_lease.py +225 -0
- ksadk/plugins/providers/dsh_mcp.py +163 -1
- ksadk/plugins/providers/harness.py +247 -34
- ksadk/plugins/providers/harness_context.py +61 -0
- ksadk/plugins/providers/harness_contributions.py +241 -0
- ksadk/plugins/providers/harness_delegation.py +91 -14
- ksadk/plugins/providers/harness_hooks.py +121 -0
- ksadk/plugins/providers/harness_managed.py +269 -175
- ksadk/plugins/providers/harness_tools.py +165 -36
- ksadk/plugins/providers/legacy_catalog.py +1 -1
- ksadk/plugins/providers/mcp_projection.py +100 -3
- ksadk/plugins/providers/platform_resources.py +16 -6
- ksadk/plugins/teams/application.py +3 -143
- ksadk/plugins/teams/build_artifacts.py +460 -0
- ksadk/plugins/teams/cloud_contract_fingerprints.py +22 -0
- ksadk/plugins/teams/cloud_contracts.py +928 -0
- ksadk/plugins/teams/cloud_permits.py +250 -0
- ksadk/plugins/teams/domain.py +201 -148
- ksadk/plugins/teams/effect_contracts.py +255 -0
- ksadk/plugins/teams/execution_projection.py +255 -0
- ksadk/plugins/teams/leader_decisions.py +106 -0
- ksadk/plugins/teams/postgres_store.py +299 -85
- ksadk/plugins/teams/release_contracts.py +60 -0
- ksadk/plugins/teams/runtime.py +116 -40
- ksadk/plugins/teams/store.py +214 -6
- ksadk/plugins/teams/task_decisions.py +21 -8
- ksadk/plugins/teams/tool_service.py +152 -0
- ksadk/plugins/teams/transport.py +8 -3
- ksadk/resource_runtime/skill_runtime.py +3 -0
- ksadk/resource_runtime/socket_server.py +11 -0
- ksadk/resource_runtime/worker.py +28 -4
- ksadk/runners/_adk_a2a_stream.py +122 -0
- ksadk/runners/_adk_canonical_stream.py +474 -0
- ksadk/runners/_langgraph_canonical_streams.py +527 -0
- ksadk/runners/_langgraph_runner_streams.py +6 -400
- ksadk/runners/_langgraph_tool_projection.py +86 -0
- ksadk/runners/_langgraph_tools_transformer.py +27 -0
- ksadk/runners/adk_runner.py +195 -290
- ksadk/runners/base_runner.py +6 -5
- ksadk/runners/langgraph_runner.py +82 -86
- ksadk/runners/utils/loader.py +28 -14
- ksadk/runtime/_runner_adapter/a2ui_surface.py +145 -0
- ksadk/runtime/_runner_adapter/gateway_approvals.py +93 -0
- ksadk/runtime/_runner_adapter/stream_mapping.py +83 -128
- ksadk/runtime/adapter.py +40 -3
- ksadk/runtime/conversation_execution.py +4 -2
- ksadk/runtime/executor.py +97 -7
- ksadk/runtime/factory.py +13 -6
- ksadk/runtime/framework_adapters.py +184 -10
- ksadk/runtime/hosted_finalizer.py +4 -6
- ksadk/runtime/launch.py +2 -0
- ksadk/runtime/runner_adapter.py +123 -13
- ksadk/runtime_context.py +2 -0
- ksadk/sandbox/backends/e2b.py +30 -4
- ksadk/sandbox/backends/local_process.py +10 -0
- ksadk/sandbox/e2b_connection.py +9 -1
- ksadk/sandbox/local_controls.py +32 -2
- ksadk/sandbox/local_launcher.py +34 -0
- ksadk/server/factory.py +178 -25
- ksadk/server/history_deadline.py +158 -0
- ksadk/server/history_page_cache.py +129 -0
- ksadk/server/routes/checkpoint_audit.py +88 -0
- ksadk/server/routes/checkpoint_listing.py +294 -0
- ksadk/server/routes/checkpoint_resolution.py +73 -20
- ksadk/server/routes/control.py +51 -3
- ksadk/server/routes/display_projection.py +154 -0
- ksadk/server/routes/kernel_ingress.py +17 -2
- ksadk/server/routes/misc.py +102 -12
- ksadk/server/routes/models.py +25 -1
- ksadk/server/routes/openai_compat.py +6 -0
- ksadk/server/routes/projection.py +159 -216
- ksadk/server/routes/run.py +6 -2
- ksadk/server/routes/sessions.py +301 -342
- ksadk/server/routes/streaming.py +68 -15
- ksadk/server/routes/tool_receipt_claim_routes.py +107 -0
- ksadk/server/routes/workspace.py +5 -2
- ksadk/server/static/assets/{ArtifactsPanel-C1YoaKhx.js → ArtifactsPanel-CILaW-fC.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-DHuAWfr5.js → CodeBlock-BVrNVtJC.js} +1 -1
- ksadk/server/static/assets/{MathMessageMarkdown-cvdrBwYr.js → MathMessageMarkdown-Dp7c4wWD.js} +1 -1
- ksadk/server/static/assets/{MermaidBlock-DeBkbJvI.js → MermaidBlock-Dxop8Rd7.js} +6 -6
- ksadk/server/static/assets/{NativeTerminalPanel-oJj44_sV.js → NativeTerminalPanel-Cjjz8B30.js} +1 -1
- ksadk/server/static/assets/{abnfDiagram-VCTEODGH-Dhfv25o2.js → abnfDiagram-VCTEODGH-ckWDmOzw.js} +1 -1
- ksadk/server/static/assets/{arc-C35w-pn1.js → arc-DqxJede-.js} +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-pn_DuLy6.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-FoMY_u6D.js → architectureDiagram-5GKGNRK7-SEQA4bVi.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-NRAW4CY4-zD4Rt7oE.js → blockDiagram-NRAW4CY4-pM0B-6NJ.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-BCtGGkhN.js → c4Diagram-UCG6FXSJ-m2tuCNVq.js} +1 -1
- ksadk/server/static/assets/channel-fySsnkft.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-BheGxKRQ.js +1 -0
- ksadk/server/static/assets/{chunk-5VM5RSS4-C2Ms13_k.js → chunk-5VM5RSS4-GJHDr9Ww.js} +1 -1
- ksadk/server/static/assets/{chunk-F27PBJKO-BoTj-qgx.js → chunk-F27PBJKO-CbAN45AV.js} +1 -1
- ksadk/server/static/assets/{chunk-G27WJ6UU-DOMyyjHH.js → chunk-G27WJ6UU-D5ngbbzF.js} +1 -1
- ksadk/server/static/assets/{chunk-JWPE2WC7-DbJJqDli.js → chunk-JWPE2WC7-Cc5IwuYC.js} +1 -1
- ksadk/server/static/assets/{chunk-LCL6LL3I-CLuRCt_W.js → chunk-LCL6LL3I-CprgDDdJ.js} +1 -1
- ksadk/server/static/assets/{chunk-POPQ4Y6H-D0Dz847e.js → chunk-POPQ4Y6H-CDZhSy82.js} +1 -1
- ksadk/server/static/assets/{chunk-RHFEMEQ7-BWSRzEcd.js → chunk-RHFEMEQ7-CZchUNro.js} +1 -1
- ksadk/server/static/assets/{chunk-SVP7TREG-CPoHqkCY.js → chunk-SVP7TREG-BVruqk6T.js} +1 -1
- ksadk/server/static/assets/{chunk-XXDRQBXY-Bx1jS-X-.js → chunk-XXDRQBXY-4ld9SxPN.js} +1 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-DSfLtNYm.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DSfLtNYm.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-JH36ORCC-LzyWm4m0.js → cose-bilkent-JH36ORCC-Dmyyk_Vp.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-PFWIGtvA.js +1 -0
- ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-BlW_bHED.js → cynefinDiagram-5FMLGOSQ-BIyq3EJb.js} +1 -1
- ksadk/server/static/assets/{dagre-3AP2YEHR-Bu_S86_i.js → dagre-3AP2YEHR-eBw08Qdk.js} +1 -1
- ksadk/server/static/assets/{dagre-B7nCawed.js → dagre-DfvnEf45.js} +1 -1
- ksadk/server/static/assets/{diagram-S7CK7UJ4-W_Zow2Km.js → diagram-S7CK7UJ4-CUSrE3Mg.js} +1 -1
- ksadk/server/static/assets/{diagram-UQ7AKVKN-CLIKAHON.js → diagram-UQ7AKVKN-Dq5Zw2gy.js} +1 -1
- ksadk/server/static/assets/{diagram-VSXAHHWV-Dv6_QAlN.js → diagram-VSXAHHWV-DyUHfNwT.js} +1 -1
- ksadk/server/static/assets/{diagram-VX7I27RA-BWAWRDtZ.js → diagram-VX7I27RA-CREmM89O.js} +1 -1
- ksadk/server/static/assets/{diagram-Z3DM3KII-XA_rWMss.js → diagram-Z3DM3KII-Dw9zhHUK.js} +1 -1
- ksadk/server/static/assets/{dist-CGt_UGeO.js → dist-0uJ4tdx6.js} +1 -1
- ksadk/server/static/assets/{dist-C0J5_3qM.js → dist-AEv-vXf-.js} +1 -1
- ksadk/server/static/assets/{dist-CIpWk_5f.js → dist-B49GzZDb.js} +1 -1
- ksadk/server/static/assets/{dist-B3bA05-e.js → dist-B8Myiet9.js} +1 -1
- ksadk/server/static/assets/{dist-DWfdmz9s.js → dist-BBsYarrI.js} +1 -1
- ksadk/server/static/assets/{dist-BLpRy_Yx.js → dist-BQMrUwdI.js} +1 -1
- ksadk/server/static/assets/{dist-CIRMvUM4.js → dist-BX_-FENW.js} +1 -1
- ksadk/server/static/assets/{dist-BdNFAney.js → dist-CD4L6ymH.js} +1 -1
- ksadk/server/static/assets/{dist-n3n6t_FO.js → dist-CHpW1BHj.js} +1 -1
- ksadk/server/static/assets/{dist-DppE_r-D.js → dist-CVPau3tn.js} +1 -1
- ksadk/server/static/assets/{dist-qe8xjesy.js → dist-C_qdxcSH.js} +1 -1
- ksadk/server/static/assets/{dist-2vL2sAdF.js → dist-Co68Apq4.js} +1 -1
- ksadk/server/static/assets/{dist-1nXCdsej.js → dist-Cp2PaOMY.js} +1 -1
- ksadk/server/static/assets/{dist-DNKuMzWc.js → dist-CuR5Bgme.js} +1 -1
- ksadk/server/static/assets/{dist-t6MzE0jU.js → dist-DDSyLEOX.js} +1 -1
- ksadk/server/static/assets/{dist-CPyieXEf.js → dist-DUxO0R99.js} +1 -1
- ksadk/server/static/assets/{dist-DyG6Ya-z.js → dist-QzbGrED_.js} +1 -1
- ksadk/server/static/assets/{dist-0X_j2Rcc.js → dist-bupkyEBZ.js} +1 -1
- ksadk/server/static/assets/{dist-mqD5TZup.js → dist-cxTGfdqx.js} +1 -1
- ksadk/server/static/assets/{dist-M-SrdhhZ.js → dist-hL5p1til.js} +1 -1
- ksadk/server/static/assets/{dist-D-92S-Fd.js → dist-lOy23y43.js} +1 -1
- ksadk/server/static/assets/{dist-BO_UwatH.js → dist-pq-nD33R.js} +1 -1
- ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-BfCzF1Xi.js → ebnfDiagram-PWID7BFC-BS5LdNoR.js} +1 -1
- ksadk/server/static/assets/{erDiagram-SSCWMZ5O-Dpz9_0zn.js → erDiagram-SSCWMZ5O-Bv1QtiY-.js} +1 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-DsM4upQX.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-D5NA16k9.js +1 -0
- ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-DDaG1f4_.js → ganttDiagram-EL5Y4UJY-musi-e0G.js} +1 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-DUCVz-ih.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-DcxzRwYC.js → gitGraphDiagram-WWUBYQGX-DH37EGkG.js} +1 -1
- ksadk/server/static/assets/index-CZdkAvsv.js +244 -0
- ksadk/server/static/assets/index-CvXdHgF3.css +2 -0
- ksadk/server/static/assets/info-A6RAGUB7-rw0ZNHZp.js +1 -0
- ksadk/server/static/assets/{infoDiagram-RXCK75RN-CYMdn6lQ.js → infoDiagram-RXCK75RN-C1kEtv2y.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CLHFAD6c.js → ishikawaDiagram-5VMMS53U-BCNPyMka.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-EYS64GPL-BHSKQGAl.js → journeyDiagram-EYS64GPL--cDbKnjP.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-3QL26DDD-D5W3tjTT.js → kanban-definition-3QL26DDD-R1rAVw2f.js} +1 -1
- ksadk/server/static/assets/{katex-mtjOi4KM.js → katex-BT-X-V7U.js} +1 -1
- ksadk/server/static/assets/{linear-BETqsxE_.js → linear-DTR631iG.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-DPWrvs90.js → mermaid-parser.core-DfFzJhX8.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-CJG2mfBP.js → mindmap-definition-FBJOCRG2-D4by_rmk.js} +1 -1
- ksadk/server/static/assets/packet-AYTQ26CC-Ca4Hvki9.js +1 -0
- ksadk/server/static/assets/{pegDiagram-XKGWAZYB-GjAPNaqn.js → pegDiagram-XKGWAZYB-xWXPEh0c.js} +1 -1
- ksadk/server/static/assets/pie-WAS4IAKB-hwiz6fbw.js +1 -0
- ksadk/server/static/assets/{pieDiagram-E7YTZNPT-ToIewrqr.js → pieDiagram-E7YTZNPT-BudBDlCI.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-4d78KiEY.js → quadrantDiagram-AXDQQJYC-DXZ0PCJF.js} +1 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-BR1oZXLM.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-DfgEISfX.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-CWOC3rdk.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CiRvHCLY.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-DSDDyJ2f.js +1 -0
- ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-DKzx4xfv.js → railroadDiagram-O6MQD6OU-BdAYRYB8.js} +1 -1
- ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-CJYljxQS.js → requirementDiagram-EFPCY7ZU-CBBmaL70.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-DLU2fV1w.js → sankeyDiagram-P5KCCOFB-Doc3rdwp.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-CVqysrA9.js → sequenceDiagram-WJ2MYXX4-0J8R8hWW.js} +1 -1
- ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-BUxfmTHc.js → sizeCapture-X5ZJPWSS-CfFLlWsK.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-CNFgYI9E.js → stateDiagram-HBIQ2CUA-jBwkjtTy.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-Cw1fPb5w.js +1 -0
- ksadk/server/static/assets/{swimlanes-XN3QIQJK-B6qCMe8N.js → swimlanes-XN3QIQJK-B0WxTQf8.js} +1 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-Cc3JMBAF.js +8 -0
- ksadk/server/static/assets/{timeline-definition-24CTP7MA-CMD3x_U_.js → timeline-definition-24CTP7MA-BfCT_75A.js} +1 -1
- ksadk/server/static/assets/treeView-Q6P3EWNA-C05SJHxo.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-BqNLAhc3.js +1 -0
- ksadk/server/static/assets/{vennDiagram-4TSXK5OY-BqtUqvXM.js → vennDiagram-4TSXK5OY-9gX1VMDC.js} +1 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-DokNktqB.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-B5KfDjI-.js → wardleyDiagram-VM6X3IG4-sEs_BP6O.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-BaUlSZrn.js → xychartDiagram-S5SC5T6Z-Ll4jvUN9.js} +1 -1
- ksadk/server/static/index.html +2 -2
- ksadk/sessions/__init__.py +8 -1
- ksadk/sessions/_checkpoint_resume_audit.py +44 -0
- ksadk/sessions/_in_memory_query.py +112 -0
- ksadk/sessions/_local_service_sync.py +157 -156
- ksadk/sessions/_local_state_sync.py +152 -0
- ksadk/sessions/_local_tables.py +2 -0
- ksadk/sessions/_postgres_checkpoint_read.py +323 -0
- ksadk/sessions/_postgres_checkpoint_stats.py +330 -0
- ksadk/sessions/_postgres_history_read.py +678 -0
- ksadk/sessions/_postgres_schema.py +44 -2
- ksadk/sessions/_postgres_tables.py +2 -0
- ksadk/sessions/_postgres_tool_receipts.py +169 -0
- ksadk/sessions/_resilient_read.py +630 -0
- ksadk/sessions/_tool_receipt_sync.py +119 -0
- ksadk/sessions/agent_identity.py +16 -0
- ksadk/sessions/base.py +278 -0
- ksadk/sessions/db_budget.py +332 -0
- ksadk/sessions/errors.py +12 -0
- ksadk/sessions/history_budget.py +36 -0
- ksadk/sessions/history_identity.py +27 -0
- ksadk/sessions/in_memory.py +376 -113
- ksadk/sessions/local_service.py +345 -0
- ksadk/sessions/postgres_service.py +515 -549
- ksadk/sessions/resilience.py +21 -14
- ksadk/sessions/resilient.py +611 -504
- ksadk/skills/loader.py +44 -2
- ksadk/skills/runtime/backends/e2b.py +17 -14
- ksadk/skills/service_client.py +6 -1
- ksadk/studio/a2a_bindings.py +407 -0
- ksadk/studio/a2a_orchestration.py +178 -0
- ksadk/studio/active_run_output.py +92 -0
- ksadk/studio/activity_records.py +542 -0
- ksadk/studio/agent_configuration.py +173 -0
- ksadk/studio/api.py +219 -389
- ksadk/studio/api_a2a_routes.py +93 -0
- ksadk/studio/api_catalog_routes.py +13 -0
- ksadk/studio/api_cloud_chat_routes.py +382 -0
- ksadk/studio/api_contracts.py +23 -0
- ksadk/studio/attachment_store.py +14 -2
- ksadk/studio/build_resolution.py +117 -0
- ksadk/studio/build_singleflight.py +37 -0
- ksadk/studio/builder.py +20 -2
- ksadk/studio/capabilities.py +8 -3
- ksadk/studio/cloud.py +83 -377
- ksadk/studio/cloud_gateways.py +424 -0
- ksadk/studio/cloud_shared_web.py +7 -0
- ksadk/studio/codex_agent_service.py +17 -0
- ksadk/studio/codex_manifest.py +5 -1
- ksadk/studio/codex_provider_build.py +65 -0
- ksadk/studio/compiler.py +102 -6
- ksadk/studio/contract_base.py +19 -0
- ksadk/studio/contracts.py +231 -201
- ksadk/studio/dsh_application.py +58 -12
- ksadk/studio/dsh_capability_service.py +17 -171
- ksadk/studio/dsh_mcp_transport.py +191 -0
- ksadk/studio/event_store.py +17 -0
- ksadk/studio/execution_host.py +84 -11
- ksadk/studio/framework_run.py +18 -0
- ksadk/studio/interaction_submission.py +265 -0
- ksadk/studio/kernel_registry.py +12 -1
- ksadk/studio/lifecycle_status.py +43 -0
- ksadk/studio/model_buffered_wire.py +227 -0
- ksadk/studio/model_chat_tools.py +143 -0
- ksadk/studio/model_client.py +1241 -761
- ksadk/studio/model_content_stream.py +129 -0
- ksadk/studio/model_credentials.py +196 -0
- ksadk/studio/model_profile_service.py +65 -31
- ksadk/studio/model_request_projection.py +284 -0
- ksadk/studio/model_responses_content.py +296 -0
- ksadk/studio/model_usage.py +109 -0
- ksadk/studio/model_wire_failure.py +110 -0
- ksadk/studio/model_wire_identity.py +138 -0
- ksadk/studio/model_wire_snapshot.py +45 -0
- ksadk/studio/model_wire_tools.py +283 -0
- ksadk/studio/native_acceptance.py +68 -0
- ksadk/studio/native_approval.py +111 -0
- ksadk/studio/native_browser_port.py +861 -0
- ksadk/studio/native_child_mcp.py +87 -0
- ksadk/studio/native_child_publication.py +68 -0
- ksadk/studio/native_child_skills.py +72 -0
- ksadk/studio/native_child_workspace.py +176 -0
- ksadk/studio/native_command_policy.py +53 -0
- ksadk/studio/native_context_port.py +326 -0
- ksadk/studio/native_context_registration.py +54 -0
- ksadk/studio/native_document_input.py +88 -0
- ksadk/studio/native_final_shape.py +852 -0
- ksadk/studio/native_gateway_stream.py +69 -0
- ksadk/studio/native_hook_port.py +145 -0
- ksadk/studio/native_hook_registration.py +70 -0
- ksadk/studio/native_inventory_disclosure.py +223 -0
- ksadk/studio/native_kernel_admission.py +84 -0
- ksadk/studio/native_language_diagnostics.py +320 -0
- ksadk/studio/native_mcp_disclosure.py +198 -0
- ksadk/studio/native_mcp_tool_port.py +219 -0
- ksadk/studio/native_memory_acceptance.py +362 -0
- ksadk/studio/native_memory_context.py +266 -0
- ksadk/studio/native_memory_flush.py +174 -0
- ksadk/studio/native_memory_sources.py +80 -0
- ksadk/studio/native_memory_tool_port.py +360 -0
- ksadk/studio/native_memory_turn.py +183 -0
- ksadk/studio/native_model_port.py +765 -0
- ksadk/studio/native_model_recovery.py +126 -0
- ksadk/studio/native_options.py +75 -0
- ksadk/studio/native_output_fields.py +58 -0
- ksadk/studio/native_planning.py +156 -0
- ksadk/studio/native_product.py +988 -0
- ksadk/studio/native_read_budget.py +426 -0
- ksadk/studio/native_recovery.py +171 -0
- ksadk/studio/native_scope.py +35 -0
- ksadk/studio/native_session_context_port.py +141 -0
- ksadk/studio/native_session_engine.py +14 -0
- ksadk/studio/native_skill_source.py +74 -0
- ksadk/studio/native_subagent_port.py +700 -0
- ksadk/studio/native_terminal_recovery.py +95 -0
- ksadk/studio/native_test_action.py +610 -0
- ksadk/studio/native_tool_port.py +477 -0
- ksadk/studio/native_user_input.py +60 -0
- ksadk/studio/native_verification_presentation.py +65 -0
- ksadk/studio/native_workspace_diagnostics.py +183 -0
- ksadk/studio/native_workspace_port.py +43 -0
- ksadk/studio/operations.py +34 -9
- ksadk/studio/plugin_composition.py +26 -10
- ksadk/studio/plugin_kernel_adapter.py +75 -1
- ksadk/studio/plugin_native_activation.py +163 -0
- ksadk/studio/plugin_runtime.py +639 -119
- ksadk/studio/plugin_runtime_admission.py +57 -0
- ksadk/studio/presentation.py +92 -0
- ksadk/studio/public_output_store.py +69 -0
- ksadk/studio/resource_authority.py +11 -3
- ksadk/studio/resource_catalog.py +8 -12
- ksadk/studio/run_activity.py +338 -385
- ksadk/studio/run_controls.py +185 -0
- ksadk/studio/run_service.py +908 -319
- ksadk/studio/run_submission_receipts.py +68 -0
- ksadk/studio/runtime_catalog.py +23 -4
- ksadk/studio/runtime_prewarm.py +22 -0
- ksadk/studio/scheduler_assistant.py +4 -1
- ksadk/studio/service.py +356 -282
- ksadk/studio/service_settings.py +229 -0
- ksadk/studio/shared_web.py +393 -169
- ksadk/studio/shared_web_response_events.py +180 -0
- ksadk/studio/shared_web_run_state.py +133 -0
- ksadk/studio/skill_discovery.py +305 -3
- ksadk/studio/static/assets/ChannelsPage-xX5HlMId.js +8 -0
- ksadk/studio/static/assets/{CodeBlock-DMIf4h33-UIqo-BPW.js → CodeBlock-DMIf4h33-CkufcPYo.js} +3 -3
- ksadk/studio/static/assets/{MathMessageMarkdown-BesSeCYl-OhNwH4K9.js → MathMessageMarkdown-BesSeCYl-DYG1Wzbx.js} +1 -1
- ksadk/studio/static/assets/{MessageMarkdown-CwMTvgFj-g0I-I4dD.js → MessageMarkdown-CwMTvgFj-BeyLyQHu.js} +2 -2
- ksadk/studio/static/assets/TeamsPage-CCaaGaVp.js +3 -0
- ksadk/studio/static/assets/index-C7DNDik2.css +2 -0
- ksadk/studio/static/assets/index-Cy68gTlH.js +265 -0
- ksadk/studio/static/index.html +3 -3
- ksadk/studio/teams_catalog.py +33 -0
- ksadk/studio/teams_installation.py +4 -1
- ksadk/studio/teams_node.py +4 -0
- ksadk/studio/teams_node_factory.py +558 -0
- ksadk/studio/teams_node_runner.py +3 -0
- ksadk/studio/teams_node_v1.py +935 -0
- ksadk/studio/teams_remote.py +259 -37
- ksadk/studio/templates.py +1 -0
- ksadk/studio/workspace_plugins.py +3 -1
- ksadk/tools/a2a_policy.py +5 -0
- ksadk/tools/artifact_observation.py +53 -0
- ksadk/tools/captured_source_artifact.py +68 -0
- ksadk/tools/schema.py +34 -0
- ksadk/toolsets/__init__.py +82 -88
- ksadk/toolsets/a2a.py +89 -89
- ksadk/toolsets/sandbox.py +377 -6
- ksadk/toolsets/skill_management.py +315 -0
- ksadk/toolsets/tool_selection.py +94 -0
- ksadk/toolsets/workspace.py +342 -324
- ksadk/toolsets/workspace_editing.py +291 -0
- ksadk/toolsets/workspace_model_observation.py +104 -0
- ksadk/toolsets/workspace_mutation.py +75 -0
- ksadk/toolsets/workspace_read_budget.py +216 -0
- ksadk/toolsets/workspace_search.py +192 -0
- ksadk/toolsets/workspace_search_process.py +129 -0
- ksadk/toolsets/workspace_state.py +6 -0
- ksadk/version.py +1 -1
- ksadk_runtime_common/http_headers.py +18 -0
- ksadk_runtime_common/workspace_files/router.py +2 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-BCsa26zi.js +0 -1
- ksadk/server/static/assets/channel-_KDifNys.js +0 -1
- ksadk/server/static/assets/chunk-2Q5K7J3B-HdVkJ9F0.js +0 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-BVCW3ZqZ.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-BVCW3ZqZ.js +0 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-CNXjFctL.js +0 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-B5-8RH9c.js +0 -1
- ksadk/server/static/assets/flowDiagram-A5DVABFB-BppFxEKw.js +0 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-B-AhYj4C.js +0 -1
- ksadk/server/static/assets/index-BMd2mucF.css +0 -2
- ksadk/server/static/assets/index-D5qyyhTH.js +0 -244
- ksadk/server/static/assets/info-A6RAGUB7-0uiKrC35.js +0 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BVTmZ_cw.js +0 -1
- ksadk/server/static/assets/pie-WAS4IAKB-DyfxBU7V.js +0 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-FFontjL2.js +0 -1
- ksadk/server/static/assets/railroad-74A4TZTK-D0Uidzen.js +0 -1
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BOo_9T2h.js +0 -1
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-D6-BjW7Z.js +0 -1
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-CXx__yMm.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BXAFScz8.js +0 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uIQ2lJKH.js +0 -8
- ksadk/server/static/assets/treeView-Q6P3EWNA-CK5GgucZ.js +0 -1
- ksadk/server/static/assets/treemap-WGGIJYW6-Bq1u1SpG.js +0 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-QAt06uEz.js +0 -1
- ksadk/studio/static/assets/ChannelsPage-D_PGmKVq.js +0 -8
- ksadk/studio/static/assets/TeamsPage-DqX4HWKQ.js +0 -3
- ksadk/studio/static/assets/index-CfEnms6Y.css +0 -2
- ksadk/studio/static/assets/index-Dp61rOWZ.js +0 -0
- {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/top_level.txt +0 -0
|
@@ -49,7 +49,6 @@ from ksadk.conversations.runtime_metadata import (
|
|
|
49
49
|
)
|
|
50
50
|
from ksadk.conversations.runtime_observability import _latest_deferred_tool_names
|
|
51
51
|
from ksadk.conversations.runtime_payloads import PreparedConversationTurn
|
|
52
|
-
from ksadk.session_context import split_session_context
|
|
53
52
|
from ksadk.conversations.runtime_persistence import (
|
|
54
53
|
append_conversation_event,
|
|
55
54
|
append_run_resume_event,
|
|
@@ -57,20 +56,24 @@ from ksadk.conversations.runtime_persistence import (
|
|
|
57
56
|
ensure_conversation_session,
|
|
58
57
|
)
|
|
59
58
|
from ksadk.conversations.runtime_resume import (
|
|
59
|
+
ToolReceiptUncertainError,
|
|
60
60
|
_agentengine_resume_metadata,
|
|
61
61
|
_approval_decision_from_resume,
|
|
62
62
|
_approval_resume_run_mode,
|
|
63
|
+
_claim_approved_builtin_tool_resume,
|
|
63
64
|
_consecutive_approval_denials_from_events,
|
|
64
65
|
_execute_approved_builtin_tool_resume,
|
|
65
66
|
_find_tool_receipt_event_by_key,
|
|
66
67
|
_format_resume_response_text,
|
|
67
|
-
_has_pending_approval,
|
|
68
68
|
_is_approval_resume_input,
|
|
69
69
|
_is_checkpoint_resume_input,
|
|
70
70
|
_normalize_approval_resume_input,
|
|
71
71
|
_normalize_checkpoint_resume_input,
|
|
72
|
+
_raise_if_legacy_tool_receipt_checkpoint_ambiguous,
|
|
72
73
|
_tool_receipt_idempotency_key_for_resume,
|
|
74
|
+
_validate_tool_receipt_event,
|
|
73
75
|
)
|
|
76
|
+
from ksadk.conversations.tool_receipt_resume import _has_pending_approval_for_resume
|
|
74
77
|
from ksadk.ids import new_run_id
|
|
75
78
|
from ksadk.model_policy import model_policy_options_for_model
|
|
76
79
|
from ksadk.runtime_context import TRUSTED_IDENTITY_METADATA_KEY, PlatformIdentityContext
|
|
@@ -245,13 +248,41 @@ async def build_run_input(
|
|
|
245
248
|
|
|
246
249
|
existing_events = await service.get_events(resolved_session_id)
|
|
247
250
|
is_approval_resume = _is_approval_resume_input(normalized_resume_input)
|
|
248
|
-
|
|
249
|
-
|
|
251
|
+
has_pending_approval = _has_pending_approval_for_resume(
|
|
252
|
+
existing_events, normalized_resume_input
|
|
253
|
+
)
|
|
254
|
+
preclaimed_receipt = None
|
|
255
|
+
replay_candidate = normalized_resume_input
|
|
256
|
+
if is_approval_resume:
|
|
250
257
|
replay_candidate = _normalize_approval_resume_input(
|
|
251
258
|
normalized_resume_input,
|
|
252
259
|
existing_events,
|
|
253
|
-
include_resolved=
|
|
260
|
+
include_resolved=not has_pending_approval,
|
|
254
261
|
)
|
|
262
|
+
decision = replay_candidate.get("approval")
|
|
263
|
+
if not isinstance(decision, Mapping):
|
|
264
|
+
decision = _approval_decision_from_resume(replay_candidate)
|
|
265
|
+
if bool(decision.get("approved") or decision.get("approve")):
|
|
266
|
+
# Do this before persisting approval_response. An unscoped
|
|
267
|
+
# legacy receipt cannot safely be attributed to an explicit
|
|
268
|
+
# checkpoint and must never reach replay or builtin execution.
|
|
269
|
+
receipt_key = _tool_receipt_idempotency_key_for_resume(
|
|
270
|
+
session_id=resolved_session_id,
|
|
271
|
+
resume_input=replay_candidate,
|
|
272
|
+
)
|
|
273
|
+
scoped_receipt_event = (
|
|
274
|
+
_find_tool_receipt_event_by_key(existing_events, receipt_key)
|
|
275
|
+
if receipt_key
|
|
276
|
+
else None
|
|
277
|
+
)
|
|
278
|
+
if scoped_receipt_event is None:
|
|
279
|
+
_raise_if_legacy_tool_receipt_checkpoint_ambiguous(
|
|
280
|
+
session_id=resolved_session_id,
|
|
281
|
+
resume_input=replay_candidate,
|
|
282
|
+
events=existing_events,
|
|
283
|
+
)
|
|
284
|
+
existing_tool_receipt_event = None
|
|
285
|
+
if is_approval_resume and not has_pending_approval:
|
|
255
286
|
receipt_key = _tool_receipt_idempotency_key_for_resume(
|
|
256
287
|
session_id=resolved_session_id,
|
|
257
288
|
resume_input=replay_candidate,
|
|
@@ -261,10 +292,27 @@ async def build_run_input(
|
|
|
261
292
|
existing_events,
|
|
262
293
|
receipt_key,
|
|
263
294
|
)
|
|
295
|
+
replay_decision = replay_candidate.get("approval")
|
|
296
|
+
if not isinstance(replay_decision, Mapping):
|
|
297
|
+
replay_decision = _approval_decision_from_resume(replay_candidate)
|
|
298
|
+
replay_is_approved = bool(
|
|
299
|
+
replay_decision.get("approved") or replay_decision.get("approve")
|
|
300
|
+
)
|
|
264
301
|
if existing_tool_receipt_event is not None:
|
|
302
|
+
if replay_is_approved:
|
|
303
|
+
# Validate before appending the approval response. A
|
|
304
|
+
# malformed newest receipt must fail closed and must not
|
|
305
|
+
# create another approval/tool-result pair.
|
|
306
|
+
_validate_tool_receipt_event(existing_tool_receipt_event)
|
|
265
307
|
normalized_resume_input = replay_candidate
|
|
266
|
-
|
|
308
|
+
elif not replay_is_approved:
|
|
267
309
|
raise ValueError("Responses resume input requires a pending approval_request")
|
|
310
|
+
else:
|
|
311
|
+
# A prior request may have consumed approval_response before a
|
|
312
|
+
# crash left only the durable unknown claim. Discover that
|
|
313
|
+
# claim before appending another response; unknown never runs
|
|
314
|
+
# the builtin again and remains available for reconciliation.
|
|
315
|
+
normalized_resume_input = replay_candidate
|
|
268
316
|
if is_approval_resume:
|
|
269
317
|
normalized_resume_input = _normalize_approval_resume_input(
|
|
270
318
|
normalized_resume_input,
|
|
@@ -280,6 +328,36 @@ async def build_run_input(
|
|
|
280
328
|
_consecutive_approval_denials_from_events(existing_events)
|
|
281
329
|
)
|
|
282
330
|
|
|
331
|
+
# A pending approval can still race with a persisted receipt (for
|
|
332
|
+
# example, after a retry that restored the approval request but
|
|
333
|
+
# retained its tool-result ledger entry). Resolve and validate
|
|
334
|
+
# the newest matching receipt before appending approval_response.
|
|
335
|
+
# Rejections remain a harmless no-op even if an unrelated old
|
|
336
|
+
# receipt is malformed, so only approved decisions are replayed.
|
|
337
|
+
approval_decision = normalized_resume_input.get("approval")
|
|
338
|
+
if not isinstance(approval_decision, Mapping):
|
|
339
|
+
approval_decision = _approval_decision_from_resume(normalized_resume_input)
|
|
340
|
+
approval_is_approved = bool(
|
|
341
|
+
approval_decision.get("approved") or approval_decision.get("approve")
|
|
342
|
+
)
|
|
343
|
+
if approval_is_approved and existing_tool_receipt_event is None:
|
|
344
|
+
_preclaimed_receipt, preclaimed_claim = (
|
|
345
|
+
await _claim_approved_builtin_tool_resume(
|
|
346
|
+
session_id=resolved_session_id,
|
|
347
|
+
invocation_id=resolved_invocation_id,
|
|
348
|
+
resume_input=normalized_resume_input,
|
|
349
|
+
session_service_provider=provider,
|
|
350
|
+
existing_events=existing_events,
|
|
351
|
+
require_existing=not has_pending_approval,
|
|
352
|
+
)
|
|
353
|
+
)
|
|
354
|
+
if not has_pending_approval and preclaimed_claim is None:
|
|
355
|
+
raise ValueError("Responses resume input requires a pending approval_request")
|
|
356
|
+
if preclaimed_claim is not None and _preclaimed_receipt is not None:
|
|
357
|
+
if not preclaimed_claim.acquired and preclaimed_claim.state == "unknown":
|
|
358
|
+
raise ToolReceiptUncertainError(preclaimed_claim.idempotency_key)
|
|
359
|
+
preclaimed_receipt = (_preclaimed_receipt, preclaimed_claim)
|
|
360
|
+
|
|
283
361
|
resume_text = _format_resume_response_text(normalized_resume_input)
|
|
284
362
|
resume_event_metadata: dict[str, Any] = {"resume_input": normalized_resume_input}
|
|
285
363
|
if normalized_resume_input.get("call_id"):
|
|
@@ -309,6 +387,7 @@ async def build_run_input(
|
|
|
309
387
|
resume_input=normalized_resume_input,
|
|
310
388
|
session_service_provider=provider,
|
|
311
389
|
existing_events=existing_events,
|
|
390
|
+
preclaimed_receipt=preclaimed_receipt,
|
|
312
391
|
)
|
|
313
392
|
effective_resume_input = tool_resume_input or normalized_resume_input
|
|
314
393
|
if tool_resume_input is not None:
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"""Run-local presentation derived exclusively from canonical runtime facts."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from typing import Literal
|
|
7
|
+
|
|
8
|
+
from ksadk.a2a.presentation import ExecutionScopeDescriptor
|
|
9
|
+
from ksadk.conversations.contracts import ConversationItem
|
|
10
|
+
from ksadk.conversations.projector import project_conversation_item
|
|
11
|
+
from ksadk.events.canonical import (
|
|
12
|
+
InteractionRequested,
|
|
13
|
+
InteractionResolved,
|
|
14
|
+
RunCompleted,
|
|
15
|
+
RuntimeEvent,
|
|
16
|
+
)
|
|
17
|
+
from ksadk.events.content import DataContent, TextContent, ToolResultContent
|
|
18
|
+
from ksadk.events.reducer import StreamReducer
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def conversation_identity(run: str, scope: str, item: str) -> str:
|
|
22
|
+
return json.dumps([run, scope, item], ensure_ascii=False, separators=(",", ":"))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class RuntimeConversationProjection:
|
|
26
|
+
"""Replay the prefix before projecting a cursor suffix; never guess child text.
|
|
27
|
+
|
|
28
|
+
Instances belong to one run and one negotiated profile. They contain only
|
|
29
|
+
a derived view, and must be rebuilt from the authoritative event store after
|
|
30
|
+
a process restart or reconnect.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
session_id: str,
|
|
36
|
+
*,
|
|
37
|
+
profile: Literal["flat-v1", "agent-block-v1"],
|
|
38
|
+
kernel_interactions: bool = False,
|
|
39
|
+
):
|
|
40
|
+
if profile not in {"flat-v1", "agent-block-v1"}:
|
|
41
|
+
raise ValueError("unsupported presentation profile")
|
|
42
|
+
self.session_id, self.profile = session_id, profile
|
|
43
|
+
self.runtime = StreamReducer()
|
|
44
|
+
self._parents: dict[str, str] = {}
|
|
45
|
+
self._descriptors: dict[str, str] = {}
|
|
46
|
+
self._kernel_interactions = kernel_interactions
|
|
47
|
+
self._interactions: dict[tuple[str, str], str] = {}
|
|
48
|
+
|
|
49
|
+
def _identity(self, event: RuntimeEvent, scope: str, item: str) -> str:
|
|
50
|
+
if self.profile == "agent-block-v1" or scope in self._parents:
|
|
51
|
+
return conversation_identity(event.run_id, scope, item)
|
|
52
|
+
return item
|
|
53
|
+
|
|
54
|
+
def apply(self, event: RuntimeEvent) -> ConversationItem | None:
|
|
55
|
+
if not self.runtime.apply(event).applied:
|
|
56
|
+
return None
|
|
57
|
+
if event.parent_scope_id:
|
|
58
|
+
self._parents[event.scope_id] = event.parent_scope_id
|
|
59
|
+
if (
|
|
60
|
+
isinstance(event, (InteractionRequested, InteractionResolved))
|
|
61
|
+
and event.scope_id in self._parents
|
|
62
|
+
):
|
|
63
|
+
key = (event.run_id, event.interaction_id)
|
|
64
|
+
previous = self._interactions.get(key)
|
|
65
|
+
if previous is not None and previous != event.scope_id:
|
|
66
|
+
raise ValueError("interaction scope changed")
|
|
67
|
+
self._interactions[key] = event.scope_id
|
|
68
|
+
if self._kernel_interactions:
|
|
69
|
+
# The native fact establishes scope, but only the ledger's
|
|
70
|
+
# revision can authorize a user submission.
|
|
71
|
+
return None
|
|
72
|
+
projected = project_conversation_item(event, session_id=self.session_id)
|
|
73
|
+
view = self.runtime.snapshot()
|
|
74
|
+
native_item = getattr(event, "item_id", None)
|
|
75
|
+
item = next(
|
|
76
|
+
(i for i in view.items if (i.scope_id, i.item_id) == (event.scope_id, native_item)),
|
|
77
|
+
None,
|
|
78
|
+
)
|
|
79
|
+
if (
|
|
80
|
+
item
|
|
81
|
+
and event.scope_id in self._parents
|
|
82
|
+
and item.item_kind == "status"
|
|
83
|
+
and item.status == "open"
|
|
84
|
+
and not item.parts
|
|
85
|
+
):
|
|
86
|
+
return None
|
|
87
|
+
fields = projected.model_dump()
|
|
88
|
+
if item and event.scope_id in self._parents:
|
|
89
|
+
if item.item_kind in {"artifact", "tool_call", "tool_result"} and not item.parts:
|
|
90
|
+
# Native A2A declares identity before the first typed part. Do
|
|
91
|
+
# not expose an empty artifact/tool with an invented payload.
|
|
92
|
+
return None
|
|
93
|
+
if item.item_kind == "artifact" and all(isinstance(p, TextContent) for p in item.parts):
|
|
94
|
+
# A2A transports ordinary response text as an Artifact. The
|
|
95
|
+
# canonical kind stays artifact; the presentation renders its
|
|
96
|
+
# typed text parts instead of dropping them as an unknown file.
|
|
97
|
+
fields.update(
|
|
98
|
+
kind="assistant_text",
|
|
99
|
+
payload_schema_ref="conversation.item.assistant_text/v1",
|
|
100
|
+
payload={"text": "".join(p.text for p in item.parts)},
|
|
101
|
+
operation="completed" if item.status == "completed" else "replace",
|
|
102
|
+
lifecycle="completed" if item.status == "completed" else "streaming",
|
|
103
|
+
)
|
|
104
|
+
fields["item_id"] = self._identity(event, event.scope_id, projected.item_id)
|
|
105
|
+
fields["native_ref"].update(scopeId=event.scope_id, runtimeItemId=native_item)
|
|
106
|
+
if event.scope_id in self._parents:
|
|
107
|
+
fields["native_ref"]["parentScopeId"] = self._parents[event.scope_id]
|
|
108
|
+
parent = self._descriptors.get(event.scope_id)
|
|
109
|
+
if parent:
|
|
110
|
+
fields["parent_item_id"] = self._identity(event, event.scope_id, parent)
|
|
111
|
+
if self.profile == "flat-v1" or projected.kind == "reasoning":
|
|
112
|
+
fields["visibility"] = "hidden"
|
|
113
|
+
descriptor_data = (
|
|
114
|
+
next(
|
|
115
|
+
(
|
|
116
|
+
p.data
|
|
117
|
+
for p in item.parts
|
|
118
|
+
if isinstance(p, DataContent)
|
|
119
|
+
and isinstance(p.data, dict)
|
|
120
|
+
and p.data.get("schema") == "execution.scope/v1"
|
|
121
|
+
),
|
|
122
|
+
None,
|
|
123
|
+
)
|
|
124
|
+
if item
|
|
125
|
+
else None
|
|
126
|
+
)
|
|
127
|
+
if descriptor_data is not None:
|
|
128
|
+
descriptor = ExecutionScopeDescriptor.model_validate(descriptor_data)
|
|
129
|
+
self._descriptors[event.scope_id] = item.item_id
|
|
130
|
+
self._parents[event.scope_id] = descriptor.parent_scope_id
|
|
131
|
+
if self.profile == "agent-block-v1":
|
|
132
|
+
terminal = descriptor.status in {"completed", "failed", "cancelled"}
|
|
133
|
+
fields.update(
|
|
134
|
+
kind="agent",
|
|
135
|
+
payload_schema_ref="conversation.item.agent/v1",
|
|
136
|
+
capability_ref="agent.block",
|
|
137
|
+
payload=descriptor.model_dump(mode="json", by_alias=True),
|
|
138
|
+
parent_item_id=self._identity(
|
|
139
|
+
event, descriptor.trigger_ref.scope_id, descriptor.trigger_ref.item_id
|
|
140
|
+
),
|
|
141
|
+
lifecycle="failed"
|
|
142
|
+
if descriptor.status == "failed"
|
|
143
|
+
else "completed"
|
|
144
|
+
if terminal
|
|
145
|
+
else "streaming",
|
|
146
|
+
operation="completed" if terminal else "replace",
|
|
147
|
+
)
|
|
148
|
+
else:
|
|
149
|
+
fields["visibility"] = "hidden"
|
|
150
|
+
if item and item.item_kind in {"tool_call", "tool_result"}:
|
|
151
|
+
result = next((p for p in item.parts if isinstance(p, ToolResultContent)), None)
|
|
152
|
+
status = (
|
|
153
|
+
"failed"
|
|
154
|
+
if item.status == "failed" or (result and result.is_error)
|
|
155
|
+
else ("completed" if result and item.status == "completed" else "running")
|
|
156
|
+
)
|
|
157
|
+
fields["payload"].update(executionStatus=status, sourceKind=item.item_kind)
|
|
158
|
+
if isinstance(event, RunCompleted) and self.profile == "flat-v1":
|
|
159
|
+
# Pure delegation must provide explicit root output refs. Preserve
|
|
160
|
+
# an existing root answer; never aggregate arbitrary child output.
|
|
161
|
+
root_answer = any(
|
|
162
|
+
i.scope_id not in self._parents
|
|
163
|
+
and i.phase == "final_answer"
|
|
164
|
+
and i.status == "completed"
|
|
165
|
+
for i in view.items
|
|
166
|
+
)
|
|
167
|
+
if (
|
|
168
|
+
not root_answer
|
|
169
|
+
and event.output_refs
|
|
170
|
+
and all(ref.scope_id in self._parents for ref in event.output_refs)
|
|
171
|
+
):
|
|
172
|
+
texts = []
|
|
173
|
+
for ref in event.output_refs:
|
|
174
|
+
target = next(
|
|
175
|
+
i
|
|
176
|
+
for i in view.items
|
|
177
|
+
if (i.scope_id, i.item_id) == (ref.scope_id, ref.item_id)
|
|
178
|
+
)
|
|
179
|
+
texts.extend(
|
|
180
|
+
p.text
|
|
181
|
+
for p in target.parts
|
|
182
|
+
if isinstance(p, TextContent)
|
|
183
|
+
and (ref.part_id is None or p.part_id == ref.part_id)
|
|
184
|
+
)
|
|
185
|
+
fields.update(
|
|
186
|
+
item_id=conversation_identity(event.run_id, event.scope_id, "delegated-final"),
|
|
187
|
+
kind="assistant_text",
|
|
188
|
+
payload_schema_ref="conversation.item.assistant_text/v1",
|
|
189
|
+
operation="completed",
|
|
190
|
+
lifecycle="completed",
|
|
191
|
+
payload={"text": "".join(texts)},
|
|
192
|
+
)
|
|
193
|
+
return ConversationItem.model_validate(fields)
|
|
194
|
+
|
|
195
|
+
def scope_ledger_item(self, item: ConversationItem) -> ConversationItem:
|
|
196
|
+
"""Attach native child identity to the one actionable ledger projection."""
|
|
197
|
+
if item.native_ref.get("protocol") != "agent-kernel/interaction-v1":
|
|
198
|
+
return item
|
|
199
|
+
interaction_id = item.payload.get("interactionId")
|
|
200
|
+
scope = self._interactions.get((item.run_id, interaction_id))
|
|
201
|
+
if scope is None:
|
|
202
|
+
return item
|
|
203
|
+
parent = self._descriptors.get(scope)
|
|
204
|
+
return item.model_copy(
|
|
205
|
+
update={
|
|
206
|
+
"item_id": conversation_identity(item.run_id, scope, interaction_id),
|
|
207
|
+
"parent_item_id": conversation_identity(item.run_id, scope, parent)
|
|
208
|
+
if parent and self.profile == "agent-block-v1"
|
|
209
|
+
else None,
|
|
210
|
+
"native_ref": {
|
|
211
|
+
**item.native_ref,
|
|
212
|
+
"scopeId": scope,
|
|
213
|
+
"parentScopeId": self._parents[scope],
|
|
214
|
+
"runtimeItemId": interaction_id,
|
|
215
|
+
},
|
|
216
|
+
}
|
|
217
|
+
)
|
|
@@ -6,22 +6,36 @@ import time
|
|
|
6
6
|
import uuid
|
|
7
7
|
from typing import Any, Callable, Mapping, Sequence
|
|
8
8
|
|
|
9
|
-
from ksadk.conversations.context import
|
|
10
|
-
canonical_event_type,
|
|
11
|
-
)
|
|
9
|
+
from ksadk.conversations.context import canonical_event_type
|
|
12
10
|
from ksadk.conversations.model_options import normalize_model_options
|
|
13
11
|
from ksadk.conversations.run_kinds import (
|
|
14
12
|
RUN_MODE_UNKNOWN,
|
|
15
13
|
validate_run_mode,
|
|
16
14
|
)
|
|
17
15
|
from ksadk.conversations.runtime_persistence import append_conversation_event
|
|
16
|
+
from ksadk.conversations.tool_receipt_resume import (
|
|
17
|
+
ToolReceiptUncertainError, # noqa: F401
|
|
18
|
+
_claim_approved_builtin_tool_resume, # noqa: F401
|
|
19
|
+
_pending_approval_events,
|
|
20
|
+
claim_or_replay_tool_receipt,
|
|
21
|
+
replay_existing_tool_receipt_event,
|
|
22
|
+
settle_claimed_tool_receipt,
|
|
23
|
+
)
|
|
24
|
+
from ksadk.conversations.tool_receipts import _validate_tool_receipt_event # noqa: F401
|
|
18
25
|
from ksadk.events.v1_compat import EventTypeV1 as EventType
|
|
19
|
-
from ksadk.sessions import SessionEvent
|
|
20
|
-
from ksadk.tools.gateway import
|
|
21
|
-
|
|
26
|
+
from ksadk.sessions import SessionEvent, ToolReceiptClaim
|
|
27
|
+
from ksadk.tools.gateway import build_tool_receipt_idempotency_key
|
|
28
|
+
|
|
29
|
+
LEGACY_TOOL_RECEIPT_CHECKPOINT_AMBIGUITY_MESSAGE = (
|
|
30
|
+
"legacy tool receipt checkpoint identity is ambiguous; reconciliation required"
|
|
22
31
|
)
|
|
23
32
|
|
|
24
33
|
|
|
34
|
+
class LegacyToolReceiptCheckpointAmbiguityError(ValueError):
|
|
35
|
+
def __init__(self) -> None:
|
|
36
|
+
super().__init__(LEGACY_TOOL_RECEIPT_CHECKPOINT_AMBIGUITY_MESSAGE)
|
|
37
|
+
|
|
38
|
+
|
|
25
39
|
def _has_pending_approval(events: Sequence[SessionEvent]) -> bool:
|
|
26
40
|
pending = 0
|
|
27
41
|
for event in events:
|
|
@@ -41,33 +55,6 @@ def _approval_request_id_from_event(event: SessionEvent) -> str:
|
|
|
41
55
|
return str(event.id or "")
|
|
42
56
|
|
|
43
57
|
|
|
44
|
-
def _pending_approval_events(events: Sequence[SessionEvent]) -> list[SessionEvent]:
|
|
45
|
-
pending: list[SessionEvent] = []
|
|
46
|
-
for event in events:
|
|
47
|
-
event_type = _approval_lifecycle_event_type(event)
|
|
48
|
-
if event_type == "approval_request":
|
|
49
|
-
pending.append(event)
|
|
50
|
-
continue
|
|
51
|
-
if event_type != "approval_response" or not pending:
|
|
52
|
-
continue
|
|
53
|
-
resume_input = (event.metadata or {}).get("resume_input")
|
|
54
|
-
response_id = ""
|
|
55
|
-
if isinstance(resume_input, Mapping):
|
|
56
|
-
response_id = str(
|
|
57
|
-
resume_input.get("approval_request_id")
|
|
58
|
-
or resume_input.get("interrupt_id")
|
|
59
|
-
or resume_input.get("id")
|
|
60
|
-
or ""
|
|
61
|
-
)
|
|
62
|
-
if response_id:
|
|
63
|
-
pending = [
|
|
64
|
-
item for item in pending if _approval_request_id_from_event(item) != response_id
|
|
65
|
-
]
|
|
66
|
-
else:
|
|
67
|
-
pending.pop()
|
|
68
|
-
return pending
|
|
69
|
-
|
|
70
|
-
|
|
71
58
|
def _approval_request_events(events: Sequence[SessionEvent]) -> list[SessionEvent]:
|
|
72
59
|
return [
|
|
73
60
|
event for event in events if _approval_lifecycle_event_type(event) == "approval_request"
|
|
@@ -114,10 +101,10 @@ def _approval_interrupt_info_from_event(event: SessionEvent) -> dict[str, Any]:
|
|
|
114
101
|
if isinstance(request, Mapping):
|
|
115
102
|
raw_detail = request.get("detail")
|
|
116
103
|
detail = dict(raw_detail) if isinstance(raw_detail, Mapping) else {}
|
|
117
|
-
approval_id =
|
|
104
|
+
approval_id = canonical_payload.get("interaction_id") or request.get("call_id")
|
|
118
105
|
if approval_id:
|
|
119
|
-
detail
|
|
120
|
-
detail
|
|
106
|
+
detail["approval_request_id"] = approval_id
|
|
107
|
+
detail["id"] = approval_id
|
|
121
108
|
if request.get("call_id"):
|
|
122
109
|
detail.setdefault("run_id", request.get("call_id"))
|
|
123
110
|
return detail
|
|
@@ -410,9 +397,11 @@ def _tool_receipt_idempotency_key_for_resume(
|
|
|
410
397
|
run_id = _tool_resume_run_id(resume_input)
|
|
411
398
|
if not run_id:
|
|
412
399
|
return None
|
|
400
|
+
checkpoint_id = str(resume_input.get("checkpoint_id") or "").strip() or None
|
|
413
401
|
idempotency_key = build_tool_receipt_idempotency_key(
|
|
414
402
|
session_id=session_id,
|
|
415
403
|
run_id=run_id,
|
|
404
|
+
checkpoint_id=checkpoint_id,
|
|
416
405
|
tool_call_id=run_id,
|
|
417
406
|
tool_name=tool_name,
|
|
418
407
|
tool_args=dict(tool_args),
|
|
@@ -423,6 +412,9 @@ def _tool_receipt_idempotency_key_for_resume(
|
|
|
423
412
|
def _find_tool_receipt_event_by_key(
|
|
424
413
|
events: Sequence[SessionEvent],
|
|
425
414
|
idempotency_key: str,
|
|
415
|
+
*,
|
|
416
|
+
expected_receipt: Mapping[str, Any] | None = None,
|
|
417
|
+
expected_tool_args: Mapping[str, Any] | None = None,
|
|
426
418
|
) -> SessionEvent | None:
|
|
427
419
|
for event in reversed(events):
|
|
428
420
|
if event.event_type != "tool_result":
|
|
@@ -432,10 +424,68 @@ def _find_tool_receipt_event_by_key(
|
|
|
432
424
|
if not isinstance(receipt, Mapping):
|
|
433
425
|
continue
|
|
434
426
|
if str(receipt.get("idempotency_key") or "") == idempotency_key:
|
|
427
|
+
if expected_receipt is not None:
|
|
428
|
+
for field in ("tool_name", "tool_call_id", "run_id", "checkpoint_id"):
|
|
429
|
+
expected = str(expected_receipt.get(field) or "")
|
|
430
|
+
actual = str(receipt.get(field) or "")
|
|
431
|
+
if expected != actual:
|
|
432
|
+
raise ValueError(
|
|
433
|
+
f"tool receipt idempotency collision: {field} does not match"
|
|
434
|
+
)
|
|
435
|
+
if expected_tool_args is not None:
|
|
436
|
+
actual_args = metadata.get("tool_args")
|
|
437
|
+
if not isinstance(actual_args, Mapping) or dict(actual_args) != dict(
|
|
438
|
+
expected_tool_args
|
|
439
|
+
):
|
|
440
|
+
raise ValueError(
|
|
441
|
+
"tool receipt idempotency collision: tool_args do not match"
|
|
442
|
+
)
|
|
435
443
|
return event
|
|
436
444
|
return None
|
|
437
445
|
|
|
438
446
|
|
|
447
|
+
def _find_legacy_tool_receipt_event_for_resume(
|
|
448
|
+
*,
|
|
449
|
+
session_id: str,
|
|
450
|
+
resume_input: Mapping[str, Any],
|
|
451
|
+
events: Sequence[SessionEvent],
|
|
452
|
+
) -> SessionEvent | None:
|
|
453
|
+
tool_name = str(resume_input.get("tool_name") or "").strip()
|
|
454
|
+
tool_args = resume_input.get("tool_args")
|
|
455
|
+
run_id = _tool_resume_run_id(resume_input)
|
|
456
|
+
if not tool_name or not isinstance(tool_args, Mapping) or not run_id:
|
|
457
|
+
return None
|
|
458
|
+
legacy_receipt = _tool_receipt_metadata(
|
|
459
|
+
session_id=session_id,
|
|
460
|
+
run_id=run_id,
|
|
461
|
+
tool_name=tool_name,
|
|
462
|
+
tool_args=dict(tool_args),
|
|
463
|
+
tool_call_id=run_id,
|
|
464
|
+
)
|
|
465
|
+
return _find_tool_receipt_event_by_key(
|
|
466
|
+
events,
|
|
467
|
+
legacy_receipt["idempotency_key"],
|
|
468
|
+
expected_receipt=legacy_receipt,
|
|
469
|
+
expected_tool_args=tool_args,
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
def _raise_if_legacy_tool_receipt_checkpoint_ambiguous(
|
|
474
|
+
*,
|
|
475
|
+
session_id: str,
|
|
476
|
+
resume_input: Mapping[str, Any],
|
|
477
|
+
events: Sequence[SessionEvent],
|
|
478
|
+
) -> None:
|
|
479
|
+
if not str(resume_input.get("checkpoint_id") or "").strip():
|
|
480
|
+
return
|
|
481
|
+
if _find_legacy_tool_receipt_event_for_resume(
|
|
482
|
+
session_id=session_id,
|
|
483
|
+
resume_input=resume_input,
|
|
484
|
+
events=events,
|
|
485
|
+
) is not None:
|
|
486
|
+
raise LegacyToolReceiptCheckpointAmbiguityError()
|
|
487
|
+
|
|
488
|
+
|
|
439
489
|
def _latest_checkpoint_metadata_for_run(
|
|
440
490
|
events: Sequence[SessionEvent],
|
|
441
491
|
run_id: str,
|
|
@@ -468,15 +518,12 @@ async def _execute_approved_builtin_tool_resume(
|
|
|
468
518
|
resume_input: Mapping[str, Any],
|
|
469
519
|
session_service_provider: Callable[[], Any],
|
|
470
520
|
existing_events: Sequence[SessionEvent] | None = None,
|
|
521
|
+
preclaimed_receipt: tuple[dict[str, Any], ToolReceiptClaim] | None = None,
|
|
471
522
|
) -> dict[str, Any] | None:
|
|
472
523
|
approval = resume_input.get("approval")
|
|
473
524
|
if not isinstance(approval, Mapping) or not bool(approval.get("approved")):
|
|
474
525
|
return None
|
|
475
526
|
tool_name = str(resume_input.get("tool_name") or "").strip()
|
|
476
|
-
tool_func = _builtin_tool_callable(tool_name)
|
|
477
|
-
if tool_func is None:
|
|
478
|
-
return None
|
|
479
|
-
|
|
480
527
|
tool_args = resume_input.get("tool_args")
|
|
481
528
|
if not isinstance(tool_args, Mapping):
|
|
482
529
|
return None
|
|
@@ -486,6 +533,12 @@ async def _execute_approved_builtin_tool_resume(
|
|
|
486
533
|
if existing_events is None:
|
|
487
534
|
existing_events = await service.get_events(session_id)
|
|
488
535
|
checkpoint_metadata = _latest_checkpoint_metadata_for_run(existing_events, run_id)
|
|
536
|
+
requested_checkpoint_id = str(resume_input.get("checkpoint_id") or "").strip()
|
|
537
|
+
if requested_checkpoint_id:
|
|
538
|
+
checkpoint_metadata = {
|
|
539
|
+
**checkpoint_metadata,
|
|
540
|
+
"checkpoint_id": requested_checkpoint_id,
|
|
541
|
+
}
|
|
489
542
|
receipt = _tool_receipt_metadata(
|
|
490
543
|
session_id=session_id,
|
|
491
544
|
run_id=run_id,
|
|
@@ -499,41 +552,51 @@ async def _execute_approved_builtin_tool_resume(
|
|
|
499
552
|
existing_event = _find_tool_receipt_event_by_key(
|
|
500
553
|
existing_events,
|
|
501
554
|
receipt["idempotency_key"],
|
|
555
|
+
expected_receipt=receipt,
|
|
556
|
+
expected_tool_args=call_args,
|
|
502
557
|
)
|
|
558
|
+
if existing_event is None and requested_checkpoint_id:
|
|
559
|
+
# Receipts written before checkpoint-scoped keys used an empty
|
|
560
|
+
# checkpoint field. They cannot be attributed safely to this explicit
|
|
561
|
+
# checkpoint, so require reconciliation before any replay or tool call.
|
|
562
|
+
legacy_event = _find_legacy_tool_receipt_event_for_resume(
|
|
563
|
+
session_id=session_id,
|
|
564
|
+
resume_input=resume_input,
|
|
565
|
+
events=existing_events,
|
|
566
|
+
)
|
|
567
|
+
if legacy_event is not None:
|
|
568
|
+
raise LegacyToolReceiptCheckpointAmbiguityError()
|
|
503
569
|
if existing_event is not None:
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
output = {**dict(output), "replayed": True}
|
|
508
|
-
replayed_receipt = {
|
|
509
|
-
**dict((existing_metadata.get("tool_receipt") or receipt)),
|
|
510
|
-
"replayed": True,
|
|
511
|
-
"replayed_from_event_id": existing_event.id,
|
|
512
|
-
}
|
|
513
|
-
await append_conversation_event(
|
|
570
|
+
return await replay_existing_tool_receipt_event(
|
|
571
|
+
existing_event=existing_event,
|
|
572
|
+
receipt=receipt,
|
|
514
573
|
session_id=session_id,
|
|
515
|
-
author="tool",
|
|
516
|
-
role="user",
|
|
517
|
-
text=str(output),
|
|
518
574
|
invocation_id=invocation_id,
|
|
519
|
-
|
|
575
|
+
run_id=run_id,
|
|
576
|
+
tool_name=tool_name,
|
|
577
|
+
call_args=call_args,
|
|
578
|
+
resume_input=resume_input,
|
|
520
579
|
session_service_provider=session_service_provider,
|
|
521
|
-
metadata={
|
|
522
|
-
"tool_name": tool_name,
|
|
523
|
-
"tool_args": call_args,
|
|
524
|
-
"tool_output": output,
|
|
525
|
-
"run_id": run_id,
|
|
526
|
-
"approval_request_id": resume_input.get("approval_request_id")
|
|
527
|
-
or resume_input.get("interrupt_id"),
|
|
528
|
-
"tool_receipt": replayed_receipt,
|
|
529
|
-
"replayed": True,
|
|
530
|
-
},
|
|
531
580
|
)
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
581
|
+
|
|
582
|
+
tool_func = _builtin_tool_callable(tool_name)
|
|
583
|
+
if tool_func is None:
|
|
584
|
+
return None
|
|
585
|
+
|
|
586
|
+
claim, replayed = await claim_or_replay_tool_receipt(
|
|
587
|
+
service=service,
|
|
588
|
+
session_id=session_id,
|
|
589
|
+
receipt=receipt,
|
|
590
|
+
tool_name=tool_name,
|
|
591
|
+
call_args=call_args,
|
|
592
|
+
invocation_id=invocation_id,
|
|
593
|
+
preclaimed_receipt=preclaimed_receipt,
|
|
594
|
+
run_id=run_id,
|
|
595
|
+
resume_input=resume_input,
|
|
596
|
+
session_service_provider=session_service_provider,
|
|
597
|
+
)
|
|
598
|
+
if replayed is not None:
|
|
599
|
+
return replayed
|
|
537
600
|
|
|
538
601
|
try:
|
|
539
602
|
if tool_name in {"run_command", "run_code"}:
|
|
@@ -543,7 +606,15 @@ async def _execute_approved_builtin_tool_resume(
|
|
|
543
606
|
except Exception as exc:
|
|
544
607
|
output = {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
|
|
545
608
|
|
|
546
|
-
|
|
609
|
+
await settle_claimed_tool_receipt(
|
|
610
|
+
service=service,
|
|
611
|
+
claim=claim,
|
|
612
|
+
receipt=receipt,
|
|
613
|
+
session_id=session_id,
|
|
614
|
+
tool_name=tool_name,
|
|
615
|
+
call_args=call_args,
|
|
616
|
+
output=output,
|
|
617
|
+
)
|
|
547
618
|
await append_conversation_event(
|
|
548
619
|
session_id=session_id,
|
|
549
620
|
author="tool",
|