Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -683,24 +683,6 @@ def test_composite_backend_execute_without_sandbox_default():
comp.execute("ls -la")


def test_composite_backend_supports_execution_check():
"""Test the isinstance check works correctly for CompositeBackend."""
mem_store = InMemoryStore()

# CompositeBackend with sandbox default should pass isinstance check
sandbox = MockSandboxBackend(store=mem_store, namespace=lambda _rt: ("default",))
comp_with_sandbox = CompositeBackend(default=sandbox, routes={})
# Note: CompositeBackend itself has execute() method, so isinstance will pass
# but the actual support depends on the default backend
assert hasattr(comp_with_sandbox, "execute")

# CompositeBackend with non-sandbox default should still have execute() method
# but will raise NotImplementedError when called
state = StoreBackend(store=mem_store, namespace=lambda _rt: ("default",))
comp_without_sandbox = CompositeBackend(default=state, routes={})
assert hasattr(comp_without_sandbox, "execute")


def test_composite_backend_execute_with_routed_backends():
"""Test that execution doesn't interfere with file routing."""
mem_store = InMemoryStore()
Expand Down
6 changes: 0 additions & 6 deletions libs/deepagents/tests/unit_tests/backends/test_file_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

from deepagents.backends.store import StoreBackend
from deepagents.backends.utils import (
compile_grep_include_glob,
create_file_data,
file_data_to_string,
grep_matches_from_files,
Expand Down Expand Up @@ -139,11 +138,6 @@ def test_grep_glob_matches_nothing() -> None:
assert result.matches == []


def test_compile_glob_is_cached() -> None:
assert compile_grep_include_glob("*.py") is compile_grep_include_glob("*.py")
assert compile_grep_include_glob("*.py") is not compile_grep_include_glob("*.md")


def test_grep_glob_repeated_pattern_stays_correct() -> None:
first = {"/x.py": create_file_data("hit"), "/x.md": create_file_data("hit")}
second = {"/y.py": create_file_data("hit"), "/y.txt": create_file_data("hit")}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
"""Unit tests for LocalShellBackend."""

import os
import subprocess
import sys
import tempfile
import warnings
from pathlib import Path
from unittest.mock import patch

import pytest

Expand Down Expand Up @@ -69,17 +67,6 @@ def test_local_shell_backend_execute_simple_command() -> None:
assert result.truncated is False


def test_local_shell_backend_execute_starts_new_session() -> None:
"""Test that commands cannot access the parent's controlling terminal."""
completed = subprocess.CompletedProcess(args="echo hello", returncode=0, stdout="hello\n", stderr="")
with tempfile.TemporaryDirectory() as tmpdir:
backend = LocalShellBackend(root_dir=tmpdir)
with patch("subprocess.run", return_value=completed) as run:
backend.execute("echo hello")

assert run.call_args.kwargs["start_new_session"] is True


def test_local_shell_backend_cannot_open_parent_controlling_terminal(tmp_path: Path) -> None:
"""Test a command cannot open the controlling terminal owned by its parent."""
exit_code, output = _run_controlling_terminal_probe(tmp_path)
Expand Down
18 changes: 0 additions & 18 deletions libs/deepagents/tests/unit_tests/backends/test_sandbox_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -683,24 +683,6 @@ def test_grep_path_glob_is_routed_for_slash_in_glob() -> None:
assert "--include=" not in sandbox.last_command


def test_grep_path_glob_template_strips_leading_slash() -> None:
"""Anchored globs (leading /) stay relative to the search root, not the filesystem root."""
assert "lstrip" in _GREP_PATH_GLOB_TEMPLATE
assert "rel_glob" in _GREP_PATH_GLOB_TEMPLATE
# The raw glob_pat must not be passed directly to glob.glob — only rel_glob.
# Verify the template uses rel_glob in the glob() call, not glob_pat.
assert "glob.glob(rel_glob" in _GREP_PATH_GLOB_TEMPLATE
assert "glob.glob(glob_pat" not in _GREP_PATH_GLOB_TEMPLATE


def test_grep_path_glob_template_terminates_each_record() -> None:
"""Each match record is explicitly newline-terminated to prevent concatenation."""
# The template must strip the line's trailing newline and add an explicit one
# so a file whose last line lacks a final newline doesn't merge with the next.
assert "rstrip" in _GREP_PATH_GLOB_TEMPLATE
assert "line.rstrip" in _GREP_PATH_GLOB_TEMPLATE


def test_grep_path_glob_parses_multiple_matches_no_trailing_newline() -> None:
"""Two matches where the first line has no trailing newline parse correctly."""
# Simulate the fixed template output: each record explicitly newline-terminated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,6 @@ def test_kwargs_backend_returns_false(self) -> None:
"""A backend with **kwargs does not have a named `timeout` param."""
assert execute_accepts_timeout(KwargsBackend) is False

def test_result_is_cached(self) -> None:
execute_accepts_timeout(ModernBackend)
execute_accepts_timeout(ModernBackend)
info = execute_accepts_timeout.cache_info()
assert info.hits >= 1

def test_logs_warning_on_inspect_failure(self, caplog: pytest.LogCaptureFixture) -> None:
"""If inspect.signature raises, a warning is logged and False returned."""

Expand Down
44 changes: 18 additions & 26 deletions libs/deepagents/tests/unit_tests/middleware/test_compact_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
from langgraph.types import Command

from deepagents.backends.state import StateBackend
from deepagents.middleware.summarization import (
SummarizationMiddleware,
SummarizationToolMiddleware,
Expand Down Expand Up @@ -474,27 +473,25 @@ def test_cutoff_exceeds_message_count(self) -> None:
class TestCompactBackendUsage:
"""Test backend use for compact offloading."""

def test_static_backend_is_passed_to_offload(self) -> None:
"""Should pass the configured backend instance to offload."""
backend = StateBackend()
mw = _make_middleware(backend=backend)
messages = _make_messages(10)
runtime = _make_runtime(messages)

with (
patch.object(mw._summarization, "_determine_cutoff_index", return_value=4),
patch.object(
mw._summarization,
"_partition_messages",
side_effect=lambda msgs, idx: (msgs[:idx], msgs[idx:]),
),
patch.object(mw._summarization, "_create_summary", return_value="Summary."),
patch.object(mw._summarization, "_offload_to_backend", return_value=None) as offload,
):
mw._run_compact(runtime)
def test_compact_writes_history_to_configured_backend(self) -> None:
"""Compacted history is written through the configured backend."""
backend = _make_mock_backend()
summarization = SummarizationMiddleware(
model=_make_mock_model(),
backend=backend,
trigger=("fraction", 0.85),
keep=("messages", 2),
)
middleware = SummarizationToolMiddleware(summarization)
messages = [HumanMessage(content=f"Message {index}") for index in range(9)]
messages.append(_ai_message_with_usage(120_000))
result = middleware._run_compact(_make_runtime(messages))

offload.assert_called_once()
assert offload.call_args.args[0] is backend
event = result.update["_summarization_event"]
backend.write.assert_called_once()
path, content = backend.write.call_args.args
assert path == event["file_path"]
assert "Message 0" in content


class TestComputeStateCutoff:
Expand Down Expand Up @@ -650,11 +647,6 @@ def test_trigger_clauses_are_preferred_over_legacy_conditions(self) -> None:
result = mw._run_compact(runtime)
assert "_summarization_event" in result.update

def test_dict_trigger_constructs_langchain_trigger_clauses(self) -> None:
"""Dict trigger input should populate LangChain's canonical trigger clauses."""
mw = _make_middleware_with_trigger({"tokens": 100_000, "messages": 6})
assert mw._summarization._lc_helper._trigger_clauses == [{"tokens": 100_000, "messages": 6}]

def test_dict_clause_list_uses_or_semantics(self) -> None:
"""Multiple dict trigger clauses use OR semantics for compact eligibility."""
mw = _make_middleware_with_trigger(("tokens", 100_000))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,6 @@ def test_max_iterations_non_int_rejected(self) -> None:
with pytest.raises(TypeError):
RubricMiddleware(model=_STUB_MODEL, max_iterations="3") # type: ignore[arg-type]

def test_tools_default_to_empty(self) -> None:
mw = RubricMiddleware(model=_STUB_MODEL)
assert mw._tools == []

def test_tools_propagated(self) -> None:
@tool
def my_tool(query: str) -> str:
Expand Down
29 changes: 0 additions & 29 deletions libs/deepagents/tests/unit_tests/test_artifacts_root.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,12 @@ def test_custom_artifacts_root(self) -> None:


class TestFilesystemMiddlewareArtifactsRoot:
def test_default_prefixes(self) -> None:
mw = FilesystemMiddleware()
assert mw._large_tool_results_prefix == "/large_tool_results"
assert mw._conversation_history_prefix == "/conversation_history"

def test_custom_artifacts_root_from_composite_backend(self) -> None:
backend = _make_composite_backend(artifacts_root="/workspace")
mw = FilesystemMiddleware(backend=backend)
assert mw._large_tool_results_prefix == "/workspace/large_tool_results"
assert mw._conversation_history_prefix == "/workspace/conversation_history"

def test_trailing_slash_normalized(self) -> None:
backend = _make_composite_backend(artifacts_root="/workspace/")
mw = FilesystemMiddleware(backend=backend)
assert mw._large_tool_results_prefix == "/workspace/large_tool_results"
assert mw._conversation_history_prefix == "/workspace/conversation_history"

def test_root_slash_no_double_slash(self) -> None:
mw = FilesystemMiddleware()
assert mw._large_tool_results_prefix == "/large_tool_results"
assert mw._conversation_history_prefix == "/conversation_history"

def test_large_tool_result_eviction_uses_artifacts_root(self) -> None:
backend = _make_composite_backend(artifacts_root="/workspace")
mw = FilesystemMiddleware(backend=backend, tool_token_limit_before_evict=100)
Expand Down Expand Up @@ -95,12 +79,6 @@ def test_default_history_path_prefix(self) -> None:
mw = create_summarization_middleware(model, backend)
assert mw._history_path_prefix == "/conversation_history"

def test_custom_artifacts_root_from_composite_backend(self) -> None:
backend = _make_composite_backend(artifacts_root="/workspace")
model = FakeChatModel(messages=iter([]))
mw = create_summarization_middleware(model, backend)
assert mw._history_path_prefix == "/workspace/conversation_history"

def test_trailing_slash_normalized(self) -> None:
backend = _make_composite_backend(artifacts_root="/workspace/")
model = FakeChatModel(messages=iter([]))
Expand Down Expand Up @@ -135,13 +113,6 @@ def test_large_tool_result_eviction(self) -> None:
[resp] = backend.download_files(["/large_tool_results/evict_ws"])
assert resp.content is None

def test_summarization_history_prefix(self) -> None:
"""Summarization middleware uses the correct history prefix from artifacts_root."""
backend = _make_composite_backend(artifacts_root="/workspace")
model = FakeChatModel(messages=iter([]))
mw = create_summarization_middleware(model, backend)
assert mw._history_path_prefix == "/workspace/conversation_history"


class TestAsyncEvictionArtifactsRoot:
"""Tests for async eviction paths with custom artifacts_root."""
Expand Down
10 changes: 2 additions & 8 deletions libs/deepagents/tests/unit_tests/test_nemotron_ultra_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -948,20 +948,14 @@ def test_register_adds_ultra3_profiles_for_supported_providers() -> None:

assert _HARNESS_PROFILE_SUFFIX_MARKER in (profile.system_prompt_suffix or "")
assert "whole/full file" in profile.tool_description_overrides["read_file"]
assert [entry.name for entry in middleware] == [
"NemotronProgressBudgetMiddleware",
"NemotronPolicyNudgeMiddleware",
assert {entry.name for entry in middleware} >= {
"NemotronToolCallShim",
"ReadFileContinuationNoticeMiddleware",
"ToolRetryMiddleware",
"ModelRateLimitRetryMiddleware",
"ChatNVIDIAMessageCompatibilityMiddleware",
"NemotronReasoningTagCleanupMiddleware",
"NemotronTextToolCallParser",
"FollowupDisciplineMiddleware",
"EntityResolutionGuardMiddleware",
"FinalAnswerGuardMiddleware",
]
}
finally:
_HARNESS_PROFILES.clear()
_HARNESS_PROFILES.update(original)
3 changes: 1 addition & 2 deletions libs/deepagents/tests/unit_tests/test_rubric_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ def _load_example(monkeypatch: pytest.MonkeyPatch) -> ModuleType:
def test_project_is_resolved_after_dotenv_load(monkeypatch: pytest.MonkeyPatch) -> None:
module = _load_example(monkeypatch)

def load_dotenv(dotenv_path: str) -> bool:
assert dotenv_path == "settings"
def load_dotenv(_dotenv_path: str) -> bool:
monkeypatch.setenv("LANGSMITH_PROJECT", "project-from-dotenv")
return True

Expand Down