63 lines
2.3 KiB
Python
63 lines
2.3 KiB
Python
"""Multi-entity state-update coordinator (T40).
|
|
|
|
Wraps single-pair compute_state_update to run state updates for ALL
|
|
directed pairs of present entities. With 3 present entities (you, host,
|
|
guest) that's 6 directed pairs. With 2 present (you, host) it's 2 pairs.
|
|
|
|
Calls run sequentially to respect Featherless's 2-connection cap (the
|
|
client-level semaphore would serialize them anyway, but doing it here
|
|
keeps the failure surface clean — a hung pair doesn't queue behind
|
|
itself).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from chat.llm.client import LLMClient
|
|
from chat.services.state_update import StateUpdate, compute_state_update
|
|
|
|
|
|
async def compute_state_updates_for_present(
|
|
client: LLMClient,
|
|
*,
|
|
classifier_model: str,
|
|
present_ids: list[str],
|
|
present_names: dict[str, str],
|
|
personas: dict[str, str],
|
|
prior_edges: dict[tuple[str, str], dict],
|
|
recent_dialogue: list[dict],
|
|
timeout_s: float = 30.0,
|
|
) -> list[tuple[str, str, StateUpdate]]:
|
|
"""Run compute_state_update for every directed pair (src != tgt) over
|
|
``present_ids``. Returns list of ``(source_id, target_id, update)``
|
|
tuples in the natural iteration order over ``present_ids x present_ids``.
|
|
|
|
A single failing pair falls back to the schema-default StateUpdate
|
|
(zero deltas, empty facts) inside ``compute_state_update``; the batch
|
|
keeps going.
|
|
"""
|
|
out: list[tuple[str, str, StateUpdate]] = []
|
|
for src in present_ids:
|
|
for tgt in present_ids:
|
|
if src == tgt:
|
|
continue
|
|
edge = prior_edges.get((src, tgt), {})
|
|
update = await compute_state_update(
|
|
client,
|
|
model=classifier_model,
|
|
source_id=src,
|
|
target_id=tgt,
|
|
source_name=present_names.get(src, src),
|
|
source_persona=personas.get(src, "") or "",
|
|
target_name=present_names.get(tgt, tgt),
|
|
prior_affinity=int(edge.get("affinity", 50)),
|
|
prior_trust=int(edge.get("trust", 50)),
|
|
prior_summary=edge.get("summary", "") or "",
|
|
recent_dialogue=recent_dialogue,
|
|
timeout_s=timeout_s,
|
|
)
|
|
out.append((src, tgt, update))
|
|
return out
|
|
|
|
|
|
__all__ = ["compute_state_updates_for_present"]
|