refactor(agents): introduce chat/ category; dissolve top-level agents/shared

Recursive shared-folder rule: a shared/ must be shared by ALL siblings at its
level. The kernel (context, compaction, retry_after, web_search) was shared by
only 2 of the agents -- anonymous_chat + multi_agent_chat -- never by podcaster
or video_presentation. Those 2 are the "chat" category, so their shared code
belongs in that category's shared/, not the top-level one.

  app/agents/anonymous_chat/   -> app/agents/chat/anonymous_chat/
  app/agents/multi_agent_chat/ -> app/agents/chat/multi_agent_chat/
  app/agents/shared/           -> app/agents/chat/shared/   (anon<->mac kernel)

Top-level app/agents/shared/ is gone: nothing was shared across all three
categories (chat / podcaster / video_presentation).

~289 import sites rewritten (app.agents.{anonymous_chat,multi_agent_chat,shared}
-> app.agents.chat.*); all moves are git renames (history preserved).
app/agents/ now: chat/, podcaster/, video_presentation/, runtime/.
This commit is contained in:
CREDO23 2026-06-05 12:54:02 +02:00
parent d59bb2b5aa
commit 24b62a63b4
570 changed files with 712 additions and 613 deletions

View file

@ -14,14 +14,14 @@ from langgraph.graph import END, START, StateGraph
from langgraph.types import Command, interrupt
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.config import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.config import (
subagent_invoke_config,
)
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
collect_pending_tool_calls,
slice_decisions_by_tool_call,
)
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
build_task_tool_with_parent_config,
)

View file

@ -40,12 +40,12 @@ from langgraph.graph.message import add_messages
from langgraph.types import Command, Send, interrupt
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
build_lg_resume_map,
collect_pending_tool_calls,
slice_decisions_by_tool_call,
)
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
build_task_tool_with_parent_config,
)

View file

@ -47,12 +47,12 @@ from langgraph.graph.message import add_messages
from langgraph.types import Command, Send, interrupt
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
build_lg_resume_map,
collect_pending_tool_calls,
slice_decisions_by_tool_call,
)
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
build_task_tool_with_parent_config,
)

View file

@ -37,12 +37,12 @@ from langgraph.graph.message import add_messages
from langgraph.types import Command, Send, interrupt
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
build_lg_resume_map,
collect_pending_tool_calls,
slice_decisions_by_tool_call,
)
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
build_task_tool_with_parent_config,
)

View file

@ -37,12 +37,12 @@ from langgraph.graph.message import add_messages
from langgraph.types import Command, Send, interrupt
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
build_lg_resume_map,
collect_pending_tool_calls,
slice_decisions_by_tool_call,
)
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
build_task_tool_with_parent_config,
)

View file

@ -35,19 +35,19 @@ from langgraph.graph.message import add_messages
from langgraph.types import Command, Send
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
build_lg_resume_map,
collect_pending_tool_calls,
slice_decisions_by_tool_call,
)
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
build_task_tool_with_parent_config,
)
from app.agents.multi_agent_chat.shared.middleware.permissions.ask.request import (
from app.agents.chat.multi_agent_chat.shared.middleware.permissions.ask.request import (
request_permission_decision,
)
from app.agents.multi_agent_chat.shared.permissions import Rule
from app.agents.multi_agent_chat.subagents.shared.hitl.approvals.self_gated import (
from app.agents.chat.multi_agent_chat.shared.permissions import Rule
from app.agents.chat.multi_agent_chat.subagents.shared.hitl.approvals.self_gated import (
request_approval,
)

View file

@ -18,7 +18,7 @@ from langgraph.graph import END, START, StateGraph
from langgraph.types import Command
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
build_task_tool_with_parent_config,
)

View file

@ -9,7 +9,7 @@ from __future__ import annotations
from types import SimpleNamespace
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume import (
get_first_pending_subagent_interrupt,
)

View file

@ -17,7 +17,7 @@ from types import SimpleNamespace
import pytest
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.resume_routing import (
collect_pending_tool_calls,
slice_decisions_by_tool_call,
)

View file

@ -4,7 +4,7 @@ from __future__ import annotations
from langchain.tools import ToolRuntime
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.config import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.config import (
consume_surfsense_resume,
has_surfsense_resume,
)

View file

@ -30,7 +30,7 @@ from langgraph.graph import END, START, StateGraph
from langgraph.types import Send, interrupt
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
build_task_tool_with_parent_config,
)

View file

@ -16,7 +16,7 @@ from __future__ import annotations
from langchain.tools import ToolRuntime
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.config import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.config import (
subagent_invoke_config,
)

View file

@ -16,10 +16,10 @@ from langgraph.graph import END, START, StateGraph
from langgraph.types import Command
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.shared.middleware.permissions.ask.request import (
from app.agents.chat.multi_agent_chat.shared.middleware.permissions.ask.request import (
request_permission_decision,
)
from app.agents.multi_agent_chat.shared.permissions import Rule
from app.agents.chat.multi_agent_chat.shared.permissions import Rule
class _State(TypedDict, total=False):

View file

@ -13,14 +13,14 @@ from langgraph.graph.message import add_messages
from pydantic import BaseModel
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
from app.agents.multi_agent_chat.shared.middleware.permissions import (
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
from app.agents.chat.multi_agent_chat.shared.middleware.permissions import (
build_permission_mw,
)
from app.agents.multi_agent_chat.shared.middleware.permissions.ask.payload import (
from app.agents.chat.multi_agent_chat.shared.middleware.permissions.ask.payload import (
build_permission_ask_payload,
)
from app.agents.multi_agent_chat.shared.permissions import Rule, Ruleset
from app.agents.chat.multi_agent_chat.shared.permissions import Rule, Ruleset
class _NoArgs(BaseModel):

View file

@ -23,11 +23,11 @@ from langgraph.graph.message import add_messages
from langgraph.types import Command
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
from app.agents.multi_agent_chat.shared.middleware.permissions import (
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
from app.agents.chat.multi_agent_chat.shared.middleware.permissions import (
build_permission_mw,
)
from app.agents.multi_agent_chat.shared.permissions import Rule, Ruleset
from app.agents.chat.multi_agent_chat.shared.permissions import Rule, Ruleset
def _kb_style_ruleset() -> Ruleset:

View file

@ -14,11 +14,11 @@ from langgraph.types import Command
from pydantic import BaseModel
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
from app.agents.multi_agent_chat.shared.middleware.permissions import (
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
from app.agents.chat.multi_agent_chat.shared.middleware.permissions import (
build_permission_mw,
)
from app.agents.multi_agent_chat.shared.permissions import Rule, Ruleset
from app.agents.chat.multi_agent_chat.shared.permissions import Rule, Ruleset
class _NoArgs(BaseModel):

View file

@ -22,7 +22,7 @@ from langgraph.graph import END, START, StateGraph
from langgraph.types import Command
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.subagents.shared.hitl.approvals.self_gated import (
from app.agents.chat.multi_agent_chat.subagents.shared.hitl.approvals.self_gated import (
request_approval,
)

View file

@ -18,7 +18,7 @@ These tests pin the shape:
from __future__ import annotations
from app.agents.multi_agent_chat.subagents.shared.hitl.wire import (
from app.agents.chat.multi_agent_chat.subagents.shared.hitl.wire import (
LC_DECISION_APPROVE,
LC_DECISION_EDIT,
LC_DECISION_REJECT,

View file

@ -19,12 +19,12 @@ from langchain_core.language_models.fake_chat_models import (
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
from langchain_core.outputs import ChatGeneration, ChatResult
from app.agents.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
from app.agents.multi_agent_chat.shared.middleware.permissions.middleware.core import (
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
from app.agents.chat.multi_agent_chat.shared.middleware.permissions.middleware.core import (
PermissionMiddleware,
)
from app.agents.multi_agent_chat.shared.permissions import Rule, Ruleset, evaluate
from app.agents.multi_agent_chat.subagents.shared.subagent_builder import (
from app.agents.chat.multi_agent_chat.shared.permissions import Rule, Ruleset, evaluate
from app.agents.chat.multi_agent_chat.subagents.shared.subagent_builder import (
pack_subagent,
)

View file

@ -14,14 +14,14 @@ from __future__ import annotations
import pytest
from app.agents.multi_agent_chat.main_agent.system_prompt.builder.load_md import (
from app.agents.chat.multi_agent_chat.main_agent.system_prompt.builder.load_md import (
read_prompt_md,
)
from app.agents.multi_agent_chat.subagents.registry import (
from app.agents.chat.multi_agent_chat.subagents.registry import (
SUBAGENT_BUILDERS_BY_NAME,
_route_resource_package,
)
from app.agents.multi_agent_chat.subagents.shared.md_file_reader import (
from app.agents.chat.multi_agent_chat.subagents.shared.md_file_reader import (
read_md_file,
read_shared_snippet,
)

View file

@ -10,10 +10,10 @@ from __future__ import annotations
import pytest
from app.agents.multi_agent_chat.constants import (
from app.agents.chat.multi_agent_chat.constants import (
SUBAGENT_TO_REQUIRED_CONNECTOR_MAP,
)
from app.agents.multi_agent_chat.subagents.registry import (
from app.agents.chat.multi_agent_chat.subagents.registry import (
SUBAGENT_BUILDERS_BY_NAME,
)

View file

@ -87,7 +87,7 @@ class RateLimitError(Exception):
def _build_agent(primary: BaseChatModel, fallback: BaseChatModel):
from langchain.agents import create_agent
from app.agents.multi_agent_chat.shared.middleware.resilience.scoped_model_fallback import (
from app.agents.chat.multi_agent_chat.shared.middleware.resilience.scoped_model_fallback import (
ScopedModelFallbackMiddleware,
)

View file

@ -10,11 +10,11 @@ import pytest
from langchain_core.messages import ToolMessage
from langchain_core.tools import tool
from app.agents.multi_agent_chat.main_agent.middleware.action_log.middleware import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.action_log.middleware import (
ActionLogMiddleware,
ToolDefinition,
)
from app.agents.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
@dataclass
@ -60,7 +60,7 @@ def _disabled_flags() -> AgentFeatureFlags:
def patch_get_flags():
def _patch(flags: AgentFeatureFlags):
return patch(
"app.agents.multi_agent_chat.main_agent.middleware.action_log.middleware.get_flags",
"app.agents.chat.multi_agent_chat.main_agent.middleware.action_log.middleware.get_flags",
return_value=flags,
)
@ -362,7 +362,7 @@ class TestActionLogDispatch:
patch_get_flags(_enabled_flags()),
patch("app.db.shielded_async_session", side_effect=lambda: factory()),
patch(
"app.agents.multi_agent_chat.main_agent.middleware.action_log.middleware.adispatch_custom_event",
"app.agents.chat.multi_agent_chat.main_agent.middleware.action_log.middleware.adispatch_custom_event",
dispatch_mock,
),
):
@ -397,7 +397,7 @@ class TestActionLogDispatch:
patch_get_flags(_enabled_flags()),
patch("app.db.shielded_async_session", side_effect=_exploding_session),
patch(
"app.agents.multi_agent_chat.main_agent.middleware.action_log.middleware.adispatch_custom_event",
"app.agents.chat.multi_agent_chat.main_agent.middleware.action_log.middleware.adispatch_custom_event",
dispatch_mock,
),
):

View file

@ -16,7 +16,7 @@ from dataclasses import dataclass
import pytest
from app.agents.multi_agent_chat.main_agent.runtime.agent_cache_store import (
from app.agents.chat.multi_agent_chat.main_agent.runtime.agent_cache_store import (
flags_signature,
reload_for_tests,
stable_hash,

View file

@ -4,8 +4,8 @@ from __future__ import annotations
import pytest
from app.agents.multi_agent_chat.shared.errors import BusyError
from app.agents.multi_agent_chat.shared.middleware.busy_mutex import (
from app.agents.chat.multi_agent_chat.shared.errors import BusyError
from app.agents.chat.multi_agent_chat.shared.middleware.busy_mutex import (
BusyMutexMiddleware,
end_turn,
get_cancel_event,

View file

@ -10,7 +10,7 @@ from langchain_core.messages import (
ToolMessage,
)
from app.agents.shared.middleware.compaction import (
from app.agents.chat.shared.middleware.compaction import (
PROTECTED_SYSTEM_PREFIXES,
_is_protected_system_message,
_sanitize_message_content,
@ -72,7 +72,7 @@ class TestPartitionMessages:
# SurfSenseCompactionMiddleware without a real model, but the
# override path needs ``_lc_helper`` to delegate to. We mock
# that with a simple slicing partitioner equivalent to the real one.
from app.agents.shared.middleware.compaction import (
from app.agents.chat.shared.middleware.compaction import (
SurfSenseCompactionMiddleware,
)

View file

@ -7,7 +7,7 @@ from typing import Any
import pytest
from langchain_core.messages import AIMessage, HumanMessage, ToolMessage
from app.agents.multi_agent_chat.main_agent.middleware.context_editing.middleware import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.context_editing.middleware import (
SpillToBackendEdit,
_build_spill_placeholder,
)

View file

@ -6,7 +6,7 @@ import pytest
from langchain_core.messages import AIMessage
from langchain_core.tools import StructuredTool
from app.agents.multi_agent_chat.main_agent.middleware.dedup_hitl import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.dedup_hitl import (
DedupHITLToolCallsMiddleware,
)
@ -115,7 +115,7 @@ def test_full_args_dedup_keeps_distinct_calls_sharing_a_field() -> None:
With :func:`dedup_key_full_args` only fully identical arg dicts dedup.
"""
from app.agents.multi_agent_chat.shared.middleware.dedup_tool_calls import (
from app.agents.chat.multi_agent_chat.shared.middleware.dedup_tool_calls import (
dedup_key_full_args,
)
@ -159,7 +159,7 @@ def test_full_args_dedup_keeps_distinct_calls_sharing_a_field() -> None:
def test_full_args_dedup_drops_only_exact_duplicates() -> None:
from app.agents.multi_agent_chat.shared.middleware.dedup_tool_calls import (
from app.agents.chat.multi_agent_chat.shared.middleware.dedup_tool_calls import (
dedup_key_full_args,
)

View file

@ -17,7 +17,7 @@ caused two production-painful behaviors:
read-only tool calls, raising ``RejectedError("ls")``.
* Mutating connector tools got *double* prompted once via the
middleware ``ask`` and again via the per-tool ``interrupt()`` in
``app.agents.multi_agent_chat.shared.tools.hitl``.
``app.agents.chat.multi_agent_chat.shared.tools.hitl``.
These tests pin the layering so a refactor that drops the default
ruleset fails loud.
@ -27,7 +27,7 @@ from __future__ import annotations
import pytest
from app.agents.multi_agent_chat.shared.permissions import (
from app.agents.chat.multi_agent_chat.shared.permissions import (
Rule,
Ruleset,
aggregate_action,

View file

@ -10,7 +10,7 @@ from __future__ import annotations
import pytest
from app.agents.multi_agent_chat.shared.permissions import (
from app.agents.chat.multi_agent_chat.shared.permissions import (
Rule,
Ruleset,
aggregate_action,

View file

@ -5,7 +5,7 @@ from __future__ import annotations
import pytest
from langchain_core.messages import AIMessage
from app.agents.multi_agent_chat.main_agent.middleware.doom_loop.middleware import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.doom_loop.middleware import (
DoomLoopMiddleware,
_signature,
)

View file

@ -4,7 +4,7 @@ from __future__ import annotations
import pytest
from app.agents.multi_agent_chat.shared.feature_flags import (
from app.agents.chat.multi_agent_chat.shared.feature_flags import (
AgentFeatureFlags,
reload_for_tests,
)

View file

@ -10,7 +10,7 @@ from __future__ import annotations
import pytest
from app.agents.multi_agent_chat.shared.tools.hitl import (
from app.agents.chat.multi_agent_chat.shared.tools.hitl import (
DEFAULT_AUTO_APPROVED_TOOLS,
HITLResult,
request_approval,

View file

@ -15,14 +15,17 @@ from unittest.mock import AsyncMock, MagicMock
import pytest
from app.agents.multi_agent_chat.shared.mention_resolver import (
from app.agents.chat.multi_agent_chat.shared import mention_resolver
from app.agents.chat.multi_agent_chat.shared.mention_resolver import (
ResolvedMention,
ResolvedMentionSet,
resolve_mentions,
substitute_in_text,
)
from app.agents.multi_agent_chat.shared.path_resolver import DOCUMENTS_ROOT, PathIndex
from app.agents.multi_agent_chat.shared import mention_resolver
from app.agents.chat.multi_agent_chat.shared.path_resolver import (
DOCUMENTS_ROOT,
PathIndex,
)
from app.schemas.new_chat import MentionedDocumentInfo
pytestmark = pytest.mark.unit

View file

@ -5,7 +5,7 @@ from __future__ import annotations
import pytest
from langchain_core.messages import AIMessage, HumanMessage
from app.agents.multi_agent_chat.main_agent.middleware.noop_injection.middleware import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.noop_injection.middleware import (
NOOP_TOOL_NAME,
NoopInjectionMiddleware,
_last_ai_has_tool_calls,

View file

@ -8,7 +8,7 @@ from unittest.mock import MagicMock
import pytest
from langchain_core.messages import AIMessage, ToolMessage
from app.agents.multi_agent_chat.main_agent.middleware.otel_span.middleware import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.otel_span.middleware import (
OtelSpanMiddleware,
_annotate_model_response,
_annotate_tool_result,
@ -206,13 +206,13 @@ class TestMiddlewareIntegration:
duration_calls: list[dict[str, Any]] = []
token_calls: list[dict[str, Any]] = []
monkeypatch.setattr(
"app.agents.multi_agent_chat.main_agent.middleware.otel_span.middleware.ot_metrics.record_model_call_duration",
"app.agents.chat.multi_agent_chat.main_agent.middleware.otel_span.middleware.ot_metrics.record_model_call_duration",
lambda duration_ms, **attrs: duration_calls.append(
{"duration_ms": duration_ms, **attrs}
),
)
monkeypatch.setattr(
"app.agents.multi_agent_chat.main_agent.middleware.otel_span.middleware.ot_metrics.record_model_token_usage",
"app.agents.chat.multi_agent_chat.main_agent.middleware.otel_span.middleware.ot_metrics.record_model_token_usage",
lambda **attrs: token_calls.append(attrs),
)
@ -257,11 +257,11 @@ class TestMiddlewareIntegration:
errors: list[str] = []
monkeypatch.setattr(
"app.agents.multi_agent_chat.main_agent.middleware.otel_span.middleware.ot_metrics.record_tool_call_error",
"app.agents.chat.multi_agent_chat.main_agent.middleware.otel_span.middleware.ot_metrics.record_tool_call_error",
lambda *, tool_name: errors.append(tool_name),
)
monkeypatch.setattr(
"app.agents.multi_agent_chat.main_agent.middleware.otel_span.middleware.ot_metrics.record_tool_call_duration",
"app.agents.chat.multi_agent_chat.main_agent.middleware.otel_span.middleware.ot_metrics.record_tool_call_duration",
lambda *args, **kwargs: None,
)

View file

@ -7,7 +7,7 @@ from unittest.mock import AsyncMock, MagicMock
import pytest
from app.agents.multi_agent_chat.shared.path_resolver import (
from app.agents.chat.multi_agent_chat.shared.path_resolver import (
DOCUMENTS_ROOT,
PathIndex,
doc_to_virtual_path,

View file

@ -4,7 +4,7 @@ from __future__ import annotations
import pytest
from app.agents.multi_agent_chat.shared.permissions import (
from app.agents.chat.multi_agent_chat.shared.permissions import (
Rule,
Ruleset,
aggregate_action,

View file

@ -6,13 +6,13 @@ from unittest.mock import MagicMock, patch
from langchain.agents.middleware import AgentMiddleware
from app.agents.multi_agent_chat.main_agent.plugins.loader import (
from app.agents.chat.multi_agent_chat.main_agent.plugins.loader import (
PLUGIN_ENTRY_POINT_GROUP,
PluginContext,
load_allowed_plugin_names_from_env,
load_plugin_middlewares,
)
from app.agents.multi_agent_chat.main_agent.plugins.year_substituter import (
from app.agents.chat.multi_agent_chat.main_agent.plugins.year_substituter import (
_YearSubstituterMiddleware,
make_middleware as year_substituter_factory,
)
@ -66,7 +66,7 @@ class TestPluginLoaderBasics:
ep = _FakeEntryPoint("dangerous_plugin", factory)
with patch(
"app.agents.multi_agent_chat.main_agent.plugins.loader.entry_points",
"app.agents.chat.multi_agent_chat.main_agent.plugins.loader.entry_points",
return_value=[ep],
):
result = load_plugin_middlewares(
@ -78,7 +78,7 @@ class TestPluginLoaderBasics:
def test_loads_allowlisted_plugin(self) -> None:
ep = _FakeEntryPoint("year_substituter", year_substituter_factory)
with patch(
"app.agents.multi_agent_chat.main_agent.plugins.loader.entry_points",
"app.agents.chat.multi_agent_chat.main_agent.plugins.loader.entry_points",
return_value=[ep],
):
result = load_plugin_middlewares(
@ -95,7 +95,7 @@ class TestPluginLoaderIsolation:
ep = _FakeEntryPoint("buggy", crashing_factory)
with patch(
"app.agents.multi_agent_chat.main_agent.plugins.loader.entry_points",
"app.agents.chat.multi_agent_chat.main_agent.plugins.loader.entry_points",
return_value=[ep],
):
result = load_plugin_middlewares(_ctx(), allowed_plugin_names={"buggy"})
@ -107,7 +107,7 @@ class TestPluginLoaderIsolation:
ep = _FakeEntryPoint("liar", bad_factory)
with patch(
"app.agents.multi_agent_chat.main_agent.plugins.loader.entry_points",
"app.agents.chat.multi_agent_chat.main_agent.plugins.loader.entry_points",
return_value=[ep],
):
result = load_plugin_middlewares(_ctx(), allowed_plugin_names={"liar"})
@ -121,7 +121,7 @@ class TestPluginLoaderIsolation:
raise ImportError("cannot import")
with patch(
"app.agents.multi_agent_chat.main_agent.plugins.loader.entry_points",
"app.agents.chat.multi_agent_chat.main_agent.plugins.loader.entry_points",
return_value=[_BrokenEP()],
):
result = load_plugin_middlewares(_ctx(), allowed_plugin_names={"broken"})
@ -137,7 +137,7 @@ class TestPluginLoaderIsolation:
_FakeEntryPoint("crashing", crashing_factory),
_FakeEntryPoint("ok", year_substituter_factory),
]
with patch("app.agents.multi_agent_chat.main_agent.plugins.loader.entry_points", return_value=eps):
with patch("app.agents.chat.multi_agent_chat.main_agent.plugins.loader.entry_points", return_value=eps):
result = load_plugin_middlewares(
_ctx(), allowed_plugin_names={"crashing", "ok"}
)

View file

@ -1,5 +1,5 @@
r"""Tests for ``apply_litellm_prompt_caching`` in
:mod:`app.agents.multi_agent_chat.shared.prompt_caching`.
:mod:`app.agents.chat.multi_agent_chat.shared.prompt_caching`.
The helper replaces the legacy ``AnthropicPromptCachingMiddleware`` (which
never activated for our LiteLLM stack) with LiteLLM-native multi-provider
@ -34,8 +34,8 @@ from typing import Any
import pytest
from app.agents.multi_agent_chat.shared.llm_config import AgentConfig
from app.agents.multi_agent_chat.shared.prompt_caching import (
from app.agents.chat.multi_agent_chat.shared.llm_config import AgentConfig
from app.agents.chat.multi_agent_chat.shared.prompt_caching import (
apply_litellm_prompt_caching,
)

View file

@ -4,7 +4,7 @@ from __future__ import annotations
import pytest
from app.agents.shared.middleware.retry_after import (
from app.agents.chat.shared.middleware.retry_after import (
RetryAfterMiddleware,
_extract_retry_after_seconds,
_is_non_retryable,

View file

@ -7,7 +7,7 @@ from pathlib import Path
import pytest
from app.agents.multi_agent_chat.main_agent.skills.backends import (
from app.agents.chat.multi_agent_chat.main_agent.skills.backends import (
SKILLS_BUILTIN_PREFIX,
SKILLS_SPACE_PREFIX,
BuiltinSkillsBackend,

View file

@ -4,7 +4,7 @@ from __future__ import annotations
import pytest
from app.agents.multi_agent_chat.shared.state.reducers import (
from app.agents.chat.multi_agent_chat.shared.state.reducers import (
_CLEAR,
_add_unique_reducer,
_dict_merge_with_tombstones_reducer,

View file

@ -5,10 +5,12 @@ from __future__ import annotations
import pytest
from langchain_core.messages import AIMessage
from app.agents.multi_agent_chat.main_agent.middleware.tool_call_repair.middleware import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.tool_call_repair.middleware import (
ToolCallNameRepairMiddleware,
)
from app.agents.multi_agent_chat.main_agent.tools.invalid_tool import INVALID_TOOL_NAME
from app.agents.chat.multi_agent_chat.main_agent.tools.invalid_tool import (
INVALID_TOOL_NAME,
)
pytestmark = pytest.mark.unit

View file

@ -7,7 +7,7 @@ from types import SimpleNamespace
import pytest
from app.agents.multi_agent_chat.shared.tools.mcp.cache import (
from app.agents.chat.multi_agent_chat.shared.tools.mcp.cache import (
CachedMCPToolDef,
CachedMCPTools,
read_cached_tools,

View file

@ -15,7 +15,7 @@ import pypdf
import pytest
from langchain.tools import ToolRuntime
from app.agents.multi_agent_chat.subagents.builtins.deliverables.tools import (
from app.agents.chat.multi_agent_chat.subagents.builtins.deliverables.tools import (
resume as resume_tool,
)

View file

@ -44,7 +44,7 @@ def patched_globals(monkeypatch: pytest.MonkeyPatch):
-2: {"id": -2, "billing_tier": "free"},
}
monkeypatch.setattr(
"app.agents.multi_agent_chat.shared.llm_config.load_global_llm_config_by_id",
"app.agents.chat.multi_agent_chat.shared.llm_config.load_global_llm_config_by_id",
lambda cid: llm_configs.get(cid),
)

View file

@ -6,9 +6,9 @@ Ported from the dead-twin suites:
* ``tests/unit/middleware/test_filesystem_verification.py`` (desktop
multi-root mount-prefix normalization)
Both exercised ``app.agents.shared.middleware.filesystem`` (dead). This drives
Both exercised ``app.agents.chat.shared.middleware.filesystem`` (dead). This drives
the production free functions in
``app.agents.multi_agent_chat.shared.middleware.filesystem.middleware`` instead.
``app.agents.chat.multi_agent_chat.shared.middleware.filesystem.middleware`` instead.
The functions only touch ``mw._filesystem_mode`` and ``mw._get_backend`` so we
pass a lightweight fake ``mw`` rather than constructing the full middleware.
"""
@ -20,17 +20,17 @@ from types import SimpleNamespace
import pytest
from app.agents.multi_agent_chat.shared.filesystem_selection import FilesystemMode
from app.agents.multi_agent_chat.shared.middleware.filesystem.backends.multi_root_local_folder import (
from app.agents.chat.multi_agent_chat.shared.filesystem_selection import FilesystemMode
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem.backends.multi_root_local_folder import (
MultiRootLocalFolderBackend,
)
from app.agents.multi_agent_chat.shared.middleware.filesystem.middleware.mode import (
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem.middleware.mode import (
default_cwd,
)
from app.agents.multi_agent_chat.shared.middleware.filesystem.middleware.namespace_policy import (
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem.middleware.namespace_policy import (
check_cloud_write_namespace,
)
from app.agents.multi_agent_chat.shared.middleware.filesystem.middleware.path_resolution import (
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem.middleware.path_resolution import (
current_cwd,
get_contract_suggested_path,
normalize_local_mount_path,

View file

@ -1,9 +1,9 @@
"""Cloud-mode ``rm``/``rmdir`` staging tests for the LIVE filesystem middleware.
Ported from the former ``tests/unit/agents/new_chat/test_rm_rmdir_cloud.py``,
which exercised the *dead twin* ``app.agents.shared.middleware.filesystem``.
which exercised the *dead twin* ``app.agents.chat.shared.middleware.filesystem``.
This drives the production decomposed tools
(``app.agents.multi_agent_chat.shared.middleware.filesystem``) instead: it
(``app.agents.chat.multi_agent_chat.shared.middleware.filesystem``) instead: it
builds the real middleware via ``build_filesystem_mw``, pulls the real ``rm`` /
``rmdir`` tools off it, and invokes their coroutines with a stubbed
``KBPostgresBackend`` + runtime so we can assert the end-of-turn staging
@ -19,20 +19,20 @@ from unittest.mock import AsyncMock
import pytest
from app.agents.multi_agent_chat.shared.filesystem_selection import (
from app.agents.chat.multi_agent_chat.shared.filesystem_selection import (
FilesystemMode,
FilesystemSelection,
)
from app.agents.multi_agent_chat.shared.middleware.filesystem import (
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem import (
build_filesystem_mw,
)
from app.agents.multi_agent_chat.shared.middleware.filesystem.backends.kb_postgres import (
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem.backends.kb_postgres import (
KBPostgresBackend,
)
from app.agents.multi_agent_chat.shared.middleware.filesystem.backends.resolver import (
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem.backends.resolver import (
build_backend_resolver,
)
from app.agents.multi_agent_chat.shared.state.reducers import _CLEAR
from app.agents.chat.multi_agent_chat.shared.state.reducers import _CLEAR
pytestmark = pytest.mark.unit

View file

@ -2,7 +2,7 @@
Ported from ``TestModeSpecificPrompts`` in the former
``tests/unit/middleware/test_filesystem_middleware.py`` (which exercised the
dead twin ``app.agents.shared.middleware.filesystem._build_filesystem_system_prompt``).
dead twin ``app.agents.chat.shared.middleware.filesystem._build_filesystem_system_prompt``).
These drive the production ``build_system_prompt`` so the prompt the model
actually receives stays mode-scoped: cloud rules don't leak into desktop
@ -18,8 +18,8 @@ from __future__ import annotations
import pytest
from app.agents.multi_agent_chat.shared.filesystem_selection import FilesystemMode
from app.agents.multi_agent_chat.shared.middleware.filesystem.system_prompt import (
from app.agents.chat.multi_agent_chat.shared.filesystem_selection import FilesystemMode
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem.system_prompt import (
build_system_prompt,
)

View file

@ -2,10 +2,10 @@ import pytest
from langchain_core.messages import AIMessage
from langchain_core.tools import StructuredTool
from app.agents.multi_agent_chat.main_agent.middleware.dedup_hitl import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.dedup_hitl import (
DedupHITLToolCallsMiddleware,
)
from app.agents.multi_agent_chat.shared.middleware.dedup_tool_calls import (
from app.agents.chat.multi_agent_chat.shared.middleware.dedup_tool_calls import (
wrap_dedup_key_by_arg_name,
)

View file

@ -2,16 +2,16 @@ from pathlib import Path
import pytest
from app.agents.multi_agent_chat.shared.filesystem_selection import (
from app.agents.chat.multi_agent_chat.shared.filesystem_selection import (
ClientPlatform,
FilesystemMode,
FilesystemSelection,
LocalFilesystemMount,
)
from app.agents.multi_agent_chat.shared.middleware.filesystem.backends.multi_root_local_folder import (
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem.backends.multi_root_local_folder import (
MultiRootLocalFolderBackend,
)
from app.agents.multi_agent_chat.shared.middleware.filesystem.backends.resolver import (
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem.backends.resolver import (
build_backend_resolver,
)

View file

@ -15,7 +15,7 @@ from unittest.mock import AsyncMock
import numpy as np
import pytest
from app.agents.multi_agent_chat.shared.middleware import kb_persistence
from app.agents.chat.multi_agent_chat.shared.middleware import kb_persistence
from app.db import Document

View file

@ -21,7 +21,7 @@ from unittest.mock import AsyncMock, MagicMock
import pytest
from app.agents.multi_agent_chat.shared.middleware import kb_persistence
from app.agents.chat.multi_agent_chat.shared.middleware import kb_persistence
pytestmark = pytest.mark.unit

View file

@ -5,11 +5,11 @@ import json
import pytest
from langchain_core.messages import AIMessage, HumanMessage
from app.agents.multi_agent_chat.shared.middleware import knowledge_search as ks
from app.agents.multi_agent_chat.shared.middleware.filesystem.backends.document_xml import (
from app.agents.chat.multi_agent_chat.shared.middleware import knowledge_search as ks
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem.backends.document_xml import (
build_document_xml as _build_document_xml,
)
from app.agents.multi_agent_chat.shared.middleware.knowledge_search import (
from app.agents.chat.multi_agent_chat.shared.middleware.knowledge_search import (
KBSearchPlan,
KnowledgePriorityMiddleware,
_normalize_optional_date_range,

View file

@ -9,10 +9,10 @@ contract cannot silently regress.
from __future__ import annotations
from app.agents.multi_agent_chat.main_agent.middleware.knowledge_tree.middleware import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.knowledge_tree.middleware import (
KnowledgeTreeMiddleware,
)
from app.agents.multi_agent_chat.shared.path_resolver import DOCUMENTS_ROOT
from app.agents.chat.multi_agent_chat.shared.path_resolver import DOCUMENTS_ROOT
def _compute(folder_paths: list[str], doc_paths: list[str]) -> set[str]:
@ -88,7 +88,7 @@ class TestFormatTreeRendering:
folder_paths: list[str],
doc_specs: list[dict],
) -> str:
from app.agents.multi_agent_chat.shared.path_resolver import PathIndex
from app.agents.chat.multi_agent_chat.shared.path_resolver import PathIndex
index = PathIndex(
folder_paths={i + 1: p for i, p in enumerate(folder_paths)},

View file

@ -2,7 +2,7 @@ from pathlib import Path
import pytest
from app.agents.multi_agent_chat.shared.middleware.filesystem.backends.local_folder import (
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem.backends.local_folder import (
LocalFolderBackend,
)

View file

@ -2,7 +2,7 @@ from pathlib import Path
import pytest
from app.agents.multi_agent_chat.shared.middleware.filesystem.backends.multi_root_local_folder import (
from app.agents.chat.multi_agent_chat.shared.middleware.filesystem.backends.multi_root_local_folder import (
MultiRootLocalFolderBackend,
)

View file

@ -18,7 +18,7 @@ from unittest.mock import AsyncMock, patch
import pytest
from app.agents.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
from app.agents.chat.multi_agent_chat.shared.feature_flags import AgentFeatureFlags
from app.routes import agent_revert_route
from app.services.revert_service import RevertOutcome

View file

@ -91,7 +91,7 @@ async def test_global_openrouter_image_gen_sets_api_base_when_config_empty():
async def test_generate_image_tool_global_sets_api_base_when_config_empty():
"""Same defense at the agent tool entry point — both surfaces share
the same OpenRouter config payloads."""
from app.agents.multi_agent_chat.subagents.builtins.deliverables.tools import (
from app.agents.chat.multi_agent_chat.subagents.builtins.deliverables.tools import (
generate_image as gi_module,
)

View file

@ -227,7 +227,7 @@ global_llm_configs:
def test_agent_config_from_yaml_explicit_overrides_resolver():
from app.agents.multi_agent_chat.shared.llm_config import AgentConfig
from app.agents.chat.multi_agent_chat.shared.llm_config import AgentConfig
cfg_text_only = AgentConfig.from_yaml_config(
{
@ -256,7 +256,7 @@ def test_agent_config_from_yaml_explicit_overrides_resolver():
def test_agent_config_from_yaml_unannotated_uses_resolver():
"""Without an explicit YAML key, AgentConfig defers to the catalog
resolver for ``gpt-4o`` LiteLLM's map says supports_vision=True."""
from app.agents.multi_agent_chat.shared.llm_config import AgentConfig
from app.agents.chat.multi_agent_chat.shared.llm_config import AgentConfig
cfg = AgentConfig.from_yaml_config(
{
@ -275,7 +275,7 @@ def test_agent_config_auto_mode_supports_image_input():
so users can keep their selection on Auto with a vision-capable
deployment somewhere in the pool. The router's own `allowed_fails`
handles non-vision deployments via fallback."""
from app.agents.multi_agent_chat.shared.llm_config import AgentConfig
from app.agents.chat.multi_agent_chat.shared.llm_config import AgentConfig
auto = AgentConfig.from_auto_mode()
assert auto.supports_image_input is True

View file

@ -61,7 +61,7 @@ async def test_get_vision_llm_global_openrouter_sets_api_base():
return_value=cfg,
),
patch(
"app.agents.multi_agent_chat.shared.llm_config.SanitizedChatLiteLLM",
"app.agents.chat.multi_agent_chat.shared.llm_config.SanitizedChatLiteLLM",
new=FakeSanitized,
),
):

View file

@ -18,7 +18,7 @@ from langgraph.graph import END, START, StateGraph
from langgraph.types import Send, interrupt
from typing_extensions import TypedDict
from app.agents.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
from app.agents.chat.multi_agent_chat.main_agent.middleware.checkpointed_subagent_middleware.task_tool import (
build_task_tool_with_parent_config,
)
from app.tasks.chat.streaming.helpers.interrupt_inspector import (