from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
from types import SimpleNamespace
from typing import Any
import pytest
from openjiuwen_deepsearch.config.config import AgentConfig, SearchWorkflowConfig
from openjiuwen_deepsearch.framework.openjiuwen.agent.search_context import (
Action,
ActionProposal,
Result,
State,
Variable,
)
@dataclass
class DummyRuntime:
state: dict[str, Any]
def get_global_state(self, key: str) -> Any:
if "." not in key:
return self.state.get(key)
cur: Any = self.state
for part in key.split("."):
if isinstance(cur, dict):
cur = cur.get(part)
else:
cur = getattr(cur, part, None)
if cur is None:
return None
return cur
def update_global_state(self, values: dict[str, Any]) -> None:
self.state.update(values)
def base(self) -> Any:
outputs: dict[str, Any] = {}
class _State:
@staticmethod
def set_outputs(payload: dict[str, Any]) -> None:
outputs.update(payload)
return SimpleNamespace(state=lambda: _State())
@pytest.fixture
def tmp_log_dir(tmp_path: Path) -> Path:
(tmp_path / "Action").mkdir(parents=True, exist_ok=True)
(tmp_path / "Result").mkdir(parents=True, exist_ok=True)
return tmp_path
@pytest.fixture
def base_state() -> State:
return State(
id="state-1",
depth=0,
answer_variable=1,
retrieved_evidence_ids=["e1"],
state=[
Variable(
id=1,
type="City",
question_clues=["capital of france"],
discovered_clues=["eiffel tower"],
candidate="Paris",
candidate_strength=0.7,
)
],
)
@pytest.fixture
def base_action(base_state: State) -> Action:
return Action(
id="action-1",
question="What is the capital of France?",
state=base_state,
proposal=ActionProposal(direction="Check official sources", score=0.8),
messages=[{"role": "user", "content": "start"}],
)
@pytest.fixture
def base_result(base_action: Action) -> Result:
return Result(
previous_action_id=base_action.id,
messages=[{"role": "assistant", "content": "done"}],
new_states=[],
found_answer=None,
)
@pytest.fixture
def agent_config_dict() -> dict[str, Any]:
cfg = AgentConfig().model_dump()
general = cfg.setdefault("llm_config", {}).setdefault("general", {})
general["model_name"] = "mock-model"
general["base_url"] = "https://example.com"
general["api_key"] = bytearray(b"x")
return cfg
@pytest.fixture
def search_config_dict() -> dict[str, Any]:
return SearchWorkflowConfig().model_dump()