steerable-agent-runtime 0.6.60__tar.gz → 0.6.62__tar.gz
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.
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/PKG-INFO +1 -1
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/pyproject.toml +1 -1
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/approval.py +41 -10
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime.egg-info/PKG-INFO +1 -1
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_approval.py +53 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/README.md +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/setup.cfg +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/__init__.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/antihallucination.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/approval_policy.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/ask_user.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/branch.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/cache_control.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/calibration.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/compaction.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/compaction_policy.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/config.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/default.harness.json +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/default.harness.yaml +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/delegation_gate.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/errors.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/gateway_catalog.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/handoff.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/harness.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/harness_spec.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/history.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/hooks.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/llm/__init__.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/llm/anthropic_native.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/llm/compat.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/llm/errors.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/llm/google_genai.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/llm/openai_compat.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/llm/openai_responses.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/llm/parts.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/llm/presets.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/llm/system_proxy.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/loop.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/maintenance.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/mcp.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/mcp_server.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/model_catalog.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/model_info.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/model_resolve.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/native_bridge.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/observation_aging.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/orchestration.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/otel.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/plugins.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/pool.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/pricing.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/pseudo.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/recording.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/reminders.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/replay.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/resume.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/retry.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/sandboxed.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/skills.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/spill.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/storage/__init__.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/storage/in_memory.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/storage/sqlalchemy_store.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/storage/sqlite_store.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/storage/write_lease.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/subagent.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/todo.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/tokens.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/tool_presentation.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/tool_schema.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/tool_search.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/tools.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/tracing.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/transport/__init__.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/transport/fastapi_sse.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/transport/stdio_jsonrpc.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/world_state.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime.egg-info/SOURCES.txt +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime.egg-info/dependency_links.txt +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime.egg-info/requires.txt +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime.egg-info/top_level.txt +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_antihallucination.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_approval_policy.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_ask_user.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_branch.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_cache_control.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_cache_instrumentation.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_calibration.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_compaction.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_compaction_policy.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_compaction_strategy.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_config.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_content_parts.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_delegation_gate.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_error_taxonomy.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_fragment_bounds.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_gateway_catalog.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_golden.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_handoff.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_harness.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_harness_spec.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_history.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_history_persistence.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_hooks.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_in_memory_storage.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_llm_gemini_wire.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_llm_responses_wire.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_llm_stream_e2e.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_llm_wire_helpers.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_long_session.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_loop.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_loop_cancellation.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_loop_replay.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_loop_sandbox_event.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_loop_terminal.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_maintenance.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_mcp.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_mcp_server.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_model_catalog.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_model_equivalence.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_model_info.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_model_resolve.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_native_default.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_observation_aging.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_orchestration.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_otel.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_parallel_tools.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_plugins.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_provider_compat.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_provider_presets.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_pseudo.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_pyo3_api_surface.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_recording.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_reminders.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_replay_crosslang.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_resume.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_retry_hooks.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_safety_gate.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_sandboxed.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_skills.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_soft_timeout.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_spill.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_sqlite_storage.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_steer.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_storage_contract.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_stream_strip.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_subagent.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_system_proxy.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_todo.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_todo_gate.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_tokens.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_tool_exposure.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_tool_hygiene.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_tool_presentation.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_tool_router.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_tool_schema.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_tool_timeout.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_trace_recorder.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_transport_jsonrpc.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_transport_sse.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_usage_attribution.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_world_state.py +0 -0
- {steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_write_lease.py +0 -0
|
@@ -38,6 +38,7 @@ from steerable_agent_harness.policy import ToolMode, decide_tool_mode
|
|
|
38
38
|
from steerable_agent_protocol.generated import ToolCall, ToolResult
|
|
39
39
|
|
|
40
40
|
from .errors import ApprovalAborted
|
|
41
|
+
from .sandboxed import DEFAULT_SHELL_TOOLS
|
|
41
42
|
|
|
42
43
|
if TYPE_CHECKING:
|
|
43
44
|
from .loop import LoopContext, ToolExecutor
|
|
@@ -142,9 +143,9 @@ _PATH_ARG_TOOLS = {
|
|
|
142
143
|
def declared_target_paths(request: ApprovalRequest) -> list[str] | None:
|
|
143
144
|
"""Filesystem targets of a path-scoped tool, or None when the call is not one.
|
|
144
145
|
|
|
145
|
-
``None`` means
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
``None`` means this approver cannot prove the call from its path
|
|
147
|
+
arguments. Shell commands are judged separately, from the sandbox and
|
|
148
|
+
the working directory, not from the command text.
|
|
148
149
|
"""
|
|
149
150
|
if request.tool_name == "present_files":
|
|
150
151
|
files = request.arguments.get("files")
|
|
@@ -192,18 +193,46 @@ def path_inside_writable_roots(raw: str, roots: list[str]) -> bool:
|
|
|
192
193
|
return False
|
|
193
194
|
|
|
194
195
|
|
|
195
|
-
|
|
196
|
-
"""
|
|
196
|
+
def shell_stays_in_workspace(request: ApprovalRequest, roots: list[str]) -> bool:
|
|
197
|
+
"""True when a shell call's working directory is inside a writable root.
|
|
198
|
+
|
|
199
|
+
The command text is not parsed. Confinement is the OS sandbox's job:
|
|
200
|
+
writes outside the roots fail there. An omitted cwd uses the host's
|
|
201
|
+
project directory. An explicit cwd outside the roots, or one that
|
|
202
|
+
climbs out with ``..``, still needs a prompt.
|
|
203
|
+
"""
|
|
204
|
+
if request.tool_name not in DEFAULT_SHELL_TOOLS or not roots:
|
|
205
|
+
return False
|
|
206
|
+
cwd = request.arguments.get("cwd")
|
|
207
|
+
if cwd is None:
|
|
208
|
+
return True
|
|
209
|
+
if not isinstance(cwd, str) or not cwd.strip():
|
|
210
|
+
return True
|
|
211
|
+
return path_inside_writable_roots(cwd, roots)
|
|
197
212
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
213
|
+
|
|
214
|
+
class WorkspaceAutoApprover:
|
|
215
|
+
"""Skip the host prompt for work the workspace sandbox already confines.
|
|
216
|
+
|
|
217
|
+
Path-scoped tools (``local_write_file``, ``local_edit_file``, reads,
|
|
218
|
+
``present_files``) skip when every declared path is inside a writable
|
|
219
|
+
root. Shell tools skip only when the OS exec sandbox is on and the
|
|
220
|
+
working directory is inside those roots — the same split Codex uses
|
|
221
|
+
between ``workspace-write`` and ``on-request``. The allow is
|
|
222
|
+
request-scoped. The next call is judged again. Anything else falls
|
|
223
|
+
through to the inner approver.
|
|
202
224
|
"""
|
|
203
225
|
|
|
204
|
-
def __init__(
|
|
226
|
+
def __init__(
|
|
227
|
+
self,
|
|
228
|
+
inner: Approver,
|
|
229
|
+
writable_roots: list[str],
|
|
230
|
+
*,
|
|
231
|
+
sandbox_enforced: bool = False,
|
|
232
|
+
) -> None:
|
|
205
233
|
self._inner = inner
|
|
206
234
|
self._roots = [root for root in writable_roots if isinstance(root, str) and root.strip()]
|
|
235
|
+
self._sandbox_enforced = sandbox_enforced
|
|
207
236
|
|
|
208
237
|
async def approve(self, request: ApprovalRequest) -> ApprovalDecision:
|
|
209
238
|
paths = declared_target_paths(request)
|
|
@@ -213,6 +242,8 @@ class WorkspaceAutoApprover:
|
|
|
213
242
|
and all(path_inside_writable_roots(path, self._roots) for path in paths)
|
|
214
243
|
):
|
|
215
244
|
return ApprovalDecision("allow_once", "path is inside a writable project root")
|
|
245
|
+
if self._sandbox_enforced and shell_stays_in_workspace(request, self._roots):
|
|
246
|
+
return ApprovalDecision("allow_once", "command stays inside the workspace sandbox")
|
|
216
247
|
return await self._inner.approve(request)
|
|
217
248
|
|
|
218
249
|
|
|
@@ -569,3 +569,56 @@ async def test_workspace_auto_approver_does_not_cache_the_tool_name(tmp_path) ->
|
|
|
569
569
|
assert inside.kind == "allow_once"
|
|
570
570
|
assert outside.kind == "deny_once"
|
|
571
571
|
assert len(inner.requests) == 1
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
@pytest.mark.asyncio
|
|
575
|
+
async def test_workspace_auto_approver_allows_sandboxed_shell_inside_writable_roots(tmp_path) -> None:
|
|
576
|
+
from steerable_agent_runtime.approval import WorkspaceAutoApprover
|
|
577
|
+
|
|
578
|
+
project = tmp_path / "111-2"
|
|
579
|
+
project.mkdir()
|
|
580
|
+
source = tmp_path / "sources"
|
|
581
|
+
source.mkdir()
|
|
582
|
+
inner = _ScriptedApprover([ApprovalDecision("deny_once", "should not ask")])
|
|
583
|
+
approver = WorkspaceAutoApprover(inner, [str(project), str(source)], sandbox_enforced=True)
|
|
584
|
+
|
|
585
|
+
omitted = await approver.approve(_request("local_exec_shell", {"command": "mkdir notes"}))
|
|
586
|
+
nested = await approver.approve(
|
|
587
|
+
_request("local_exec_shell", {"command": "touch a.md", "cwd": str(project / "notes")})
|
|
588
|
+
)
|
|
589
|
+
linked = await approver.approve(
|
|
590
|
+
_request("bash", {"command": "ls", "cwd": str(source / "raw")})
|
|
591
|
+
)
|
|
592
|
+
relative = await approver.approve(
|
|
593
|
+
_request("shell", {"command": "pwd", "cwd": "subdir"})
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
assert omitted.kind == "allow_once"
|
|
597
|
+
assert nested.kind == "allow_once"
|
|
598
|
+
assert linked.kind == "allow_once"
|
|
599
|
+
assert relative.kind == "allow_once"
|
|
600
|
+
assert inner.requests == []
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
@pytest.mark.asyncio
|
|
604
|
+
async def test_workspace_auto_approver_asks_for_shell_that_leaves_the_sandbox(tmp_path) -> None:
|
|
605
|
+
from steerable_agent_runtime.approval import WorkspaceAutoApprover
|
|
606
|
+
|
|
607
|
+
project = tmp_path / "111-2"
|
|
608
|
+
project.mkdir()
|
|
609
|
+
inner = _ScriptedApprover([ApprovalDecision("allow_once", "user allowed")] * 3)
|
|
610
|
+
confined = WorkspaceAutoApprover(inner, [str(project)], sandbox_enforced=True)
|
|
611
|
+
open_sandbox = WorkspaceAutoApprover(inner, [str(project)], sandbox_enforced=False)
|
|
612
|
+
|
|
613
|
+
outside = await confined.approve(
|
|
614
|
+
_request("local_exec_shell", {"command": "ls", "cwd": str(tmp_path / "other")})
|
|
615
|
+
)
|
|
616
|
+
climbed = await confined.approve(
|
|
617
|
+
_request("local_exec_shell", {"command": "ls", "cwd": "../outside"})
|
|
618
|
+
)
|
|
619
|
+
unsandboxed = await open_sandbox.approve(
|
|
620
|
+
_request("local_exec_shell", {"command": "ls", "cwd": str(project)})
|
|
621
|
+
)
|
|
622
|
+
|
|
623
|
+
assert [item.kind for item in (outside, climbed, unsandboxed)] == ["allow_once"] * 3
|
|
624
|
+
assert [item.tool_name for item in inner.requests] == ["local_exec_shell"] * 3
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/src/steerable_agent_runtime/mcp.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_antihallucination.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_approval_policy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_cache_control.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_compaction_policy.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_compaction_strategy.py
RENAMED
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_content_parts.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_delegation_gate.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_error_taxonomy.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_fragment_bounds.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_gateway_catalog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_harness_spec.py
RENAMED
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_history_persistence.py
RENAMED
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_in_memory_storage.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_llm_gemini_wire.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_llm_responses_wire.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_llm_stream_e2e.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_llm_wire_helpers.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_long_session.py
RENAMED
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_loop_cancellation.py
RENAMED
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_loop_sandbox_event.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_loop_terminal.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_model_catalog.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_model_equivalence.py
RENAMED
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_model_resolve.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_native_default.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_observation_aging.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_orchestration.py
RENAMED
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_parallel_tools.py
RENAMED
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_provider_compat.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_provider_presets.py
RENAMED
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_pyo3_api_surface.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_replay_crosslang.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_soft_timeout.py
RENAMED
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_sqlite_storage.py
RENAMED
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_storage_contract.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_stream_strip.py
RENAMED
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_system_proxy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_tool_exposure.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_tool_hygiene.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_tool_presentation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_tool_timeout.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_trace_recorder.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_transport_jsonrpc.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_transport_sse.py
RENAMED
|
File without changes
|
{steerable_agent_runtime-0.6.60 → steerable_agent_runtime-0.6.62}/tests/test_usage_attribution.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|