"""工作区对话型 agent 必须绑定工作文件夹的后端守卫测试。 防的是最坑的失败模式:无 ?dir → 静默回退 agent 空家目录 → 读不到用户文件 还以 completed 收尾(假装成功)。守卫把它变成显式 400 WORKSPACE_DIR_REQUIRED。 """ from __future__ import annotations import pytest from fastapi import HTTPException from agentpaas.api.v1.agents import _require_workspace_dir class _Req: def __init__(self, ctx): self.context = ctx def test_workspace_assistant_rejects_empty_context(): agent = {"agent_template": "workspace.assistant"} with pytest.raises(HTTPException) as ei: _require_workspace_dir(agent, _Req({})) assert ei.value.status_code == 400 assert ei.value.detail["code"] == "WORKSPACE_DIR_REQUIRED" def test_workspace_assistant_rejects_nonexistent_dir(): agent = {"agent_template": "workspace.assistant"} with pytest.raises(HTTPException): _require_workspace_dir(agent, _Req({"work_dir": "/no/such/dir/zzz_nope"})) def test_workspace_assistant_accepts_valid_dir(tmp_path): agent = {"agent_template": "workspace.assistant"} # 有效目录 → 不抛 _require_workspace_dir(agent, _Req({"work_dir": str(tmp_path)})) def test_workspace_assistant_rejects_non_dict_context(): agent = {"agent_template": "workspace.assistant"} with pytest.raises(HTTPException): _require_workspace_dir(agent, _Req(None)) def test_non_workspace_agent_unaffected(): # 专项智能体不受此守卫约束(它们写各自 run 工作区) agent = {"agent_template": "research.top-journal-reviewer"} _require_workspace_dir(agent, _Req({})) # 不抛 _require_workspace_dir({"agent_template": ""}, _Req({})) # 空模板也不抛 from agentpaas.api.v1.agents import _is_native_workspace def test_native_lane_only_for_claude_code_provider(): ws = {"agent_template": "workspace.assistant"} assert _is_native_workspace(ws, {"model": {"provider": "claude-code"}}) is True # 切到 qwen/ollama/openai → 退回 react 车道(native 跑不了非 claude 模型) assert _is_native_workspace(ws, {"model": {"provider": "dashscope", "name": "qwen-max"}}) is False assert _is_native_workspace(ws, {"model": {"provider": "ollama"}}) is False assert _is_native_workspace(ws, {"model": {}}) is False # 非工作区模板:永不走 native assert _is_native_workspace({"agent_template": "research.x"}, {"model": {"provider": "claude-code"}}) is False from agentpaas.api.v1.agents import _resolve_session_cwd def test_session_cwd_aligns_with_workdir_hint(tmp_path): """会话 CWD 必须 == [工作目录] 提示(overrides.workspace_path),否则相对写入落错目录 (run_bf2405e28547:literature_map.md 落进 agent 家目录而非本 run 工作区)。""" F = tmp_path / "user_folder"; F.mkdir() ws = tmp_path / "run_xxx"; ws.mkdir() home = tmp_path / "agent_home"; home.mkdir() # 工作区对话模式:CWD = F assert _resolve_session_cwd(str(F), str(ws), str(home)) == str(F) # 专项 agent(无 inplace):CWD = 本 run workspace_path(修复点,原来错误地返回 work_dir) assert _resolve_session_cwd("", str(ws), str(home)) == str(ws) # 兜底:无 workspace_path → work_dir assert _resolve_session_cwd("", "", str(home)) == str(home) # inplace 无效路径被忽略,退回 workspace_path assert _resolve_session_cwd("/no/such/dir", str(ws), str(home)) == str(ws)