Files
Multi_Swarm_Coevolutive/tests/unit/test_hypothesis_agent.py
T
Adriano 654ab7b6d9 feat(agents): hypothesis agent with prompt template + s-expr extraction
Aggiunge HypothesisAgent che invoca LLMClient con system/user template
parametrizzati sul genoma e sul MarketSummary, poi estrae la S-expression
(da fence markdown lisp/scheme/sexp o testo nudo), la parsa e la valida.
Restituisce HypothesisProposal con strategy=None + parse_error in caso di
output malformato, mantenendo sempre il CompletionResult per accounting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 20:01:31 +02:00

94 lines
2.9 KiB
Python

from multi_swarm.agents.hypothesis import HypothesisAgent, MarketSummary
from multi_swarm.genome.hypothesis import HypothesisAgentGenome, ModelTier
from multi_swarm.llm.client import CompletionResult
def make_summary() -> MarketSummary:
return MarketSummary(
symbol="BTC/USDT",
timeframe="1h",
n_bars=1000,
return_mean=0.0001,
return_std=0.01,
skew=0.1,
kurtosis=3.5,
volatility_regime="high",
)
def test_hypothesis_agent_calls_llm_and_parses(mocker): # type: ignore[no-untyped-def]
fake_llm = mocker.MagicMock()
fake_llm.complete.return_value = CompletionResult(
text="(strategy (when (gt (indicator rsi 14) 70.0) (entry-short)))",
input_tokens=200,
output_tokens=80,
tier=ModelTier.C,
model="qwen",
)
g = HypothesisAgentGenome(
system_prompt="Pensa come un fisico.",
feature_access=["close"],
temperature=0.9,
top_p=0.95,
model_tier=ModelTier.C,
lookback_window=200,
cognitive_style="physicist",
)
agent = HypothesisAgent(llm=fake_llm)
proposal = agent.propose(g, make_summary())
assert proposal.strategy is not None
assert proposal.raw_text.startswith("(strategy")
assert proposal.completion.input_tokens == 200
fake_llm.complete.assert_called_once()
def test_hypothesis_agent_returns_none_on_parse_error(mocker): # type: ignore[no-untyped-def]
fake_llm = mocker.MagicMock()
fake_llm.complete.return_value = CompletionResult(
text="this is not s-expression",
input_tokens=200,
output_tokens=80,
tier=ModelTier.C,
model="qwen",
)
g = HypothesisAgentGenome(
system_prompt="x",
feature_access=["close"],
temperature=0.9,
top_p=0.95,
model_tier=ModelTier.C,
lookback_window=200,
cognitive_style="physicist",
)
agent = HypothesisAgent(llm=fake_llm)
proposal = agent.propose(g, make_summary())
assert proposal.strategy is None
assert proposal.parse_error is not None
def test_hypothesis_agent_extracts_sexp_from_markdown_fence(mocker): # type: ignore[no-untyped-def]
fake_llm = mocker.MagicMock()
fake_llm.complete.return_value = CompletionResult(
text=(
"Ecco la strategia:\n```lisp\n"
"(strategy (when (lt (indicator rsi 14) 30.0) (entry-long)))\n"
"```\nFatta."
),
input_tokens=200,
output_tokens=80,
tier=ModelTier.C,
model="qwen",
)
g = HypothesisAgentGenome(
system_prompt="x",
feature_access=["close"],
temperature=0.9,
top_p=0.95,
model_tier=ModelTier.C,
lookback_window=200,
cognitive_style="physicist",
)
agent = HypothesisAgent(llm=fake_llm)
proposal = agent.propose(g, make_summary())
assert proposal.strategy is not None