Files
chat/tests/test_relationship_seed.py

110 lines
3.4 KiB
Python

"""Tests for the relationship-seed service (T38).
Per Requirements §5.2, when two bots first co-appear in a chat, the user
is prompted with "Have they met before? If yes, write a short prose
seed." The prose is parsed via classifier into structured directed-edge
content for the ``botA -> botB`` and ``botB -> botA`` edges.
These tests cover:
* The happy path: a canned classifier response parses cleanly into a
populated :class:`RelationshipSeed` with both directions filled.
* Empty prose short-circuits before any classifier call (mock has no
canned responses; an accidental call would raise ``IndexError``).
* Whitespace-only prose has the same short-circuit behavior.
"""
from __future__ import annotations
import json
import pytest
from chat.llm.mock import MockLLMClient
from chat.services.relationship_seed import (
RelationshipSeed,
seed_inter_bot_edges,
)
@pytest.mark.asyncio
async def test_seed_parses_canned_prose():
canned = json.dumps(
{
"a_to_b_summary": "old college friend who now distrusts him slightly",
"a_to_b_knowledge_facts": [
"studied physics together",
"lost touch after a falling out",
],
"a_to_b_affinity_delta": 2,
"a_to_b_trust_delta": -1,
"b_to_a_summary": "former roommate; warm memories, mild resentment",
"b_to_a_knowledge_facts": ["lived together junior year"],
"b_to_a_affinity_delta": 3,
"b_to_a_trust_delta": 0,
}
)
mock = MockLLMClient(canned=[canned])
result = await seed_inter_bot_edges(
mock,
classifier_model="x",
bot_a_id="bot_a",
bot_a_name="Alice",
bot_b_id="bot_b",
bot_b_name="Bob",
relationship_prose=(
"Alice and Bob met in college. They studied physics together and "
"lived as roommates junior year, but drifted apart after a fight."
),
)
assert isinstance(result, RelationshipSeed)
assert (
result.a_to_b_summary
== "old college friend who now distrusts him slightly"
)
assert result.a_to_b_knowledge_facts == [
"studied physics together",
"lost touch after a falling out",
]
assert result.a_to_b_affinity_delta == 2
assert result.a_to_b_trust_delta == -1
assert (
result.b_to_a_summary
== "former roommate; warm memories, mild resentment"
)
assert result.b_to_a_knowledge_facts == ["lived together junior year"]
assert result.b_to_a_affinity_delta == 3
assert result.b_to_a_trust_delta == 0
@pytest.mark.asyncio
async def test_seed_empty_prose_returns_empty():
"""Empty prose short-circuits — classifier must not be called."""
mock = MockLLMClient(canned=[])
result = await seed_inter_bot_edges(
mock,
classifier_model="x",
bot_a_id="bot_a",
bot_a_name="Alice",
bot_b_id="bot_b",
bot_b_name="Bob",
relationship_prose="",
)
assert result == RelationshipSeed()
@pytest.mark.asyncio
async def test_seed_whitespace_only_prose_returns_empty():
"""Whitespace-only prose is treated the same as empty."""
mock = MockLLMClient(canned=[])
result = await seed_inter_bot_edges(
mock,
classifier_model="x",
bot_a_id="bot_a",
bot_a_name="Alice",
bot_b_id="bot_b",
bot_b_name="Bob",
relationship_prose=" \n ",
)
assert result == RelationshipSeed()