A / core /orchestrator.py
linxinhua's picture
key-pool rotation: per-session OpenAI key assignment from OPENAI_KEY_01..10 (core/orchestrator.py)
af6a95d verified
Raw
History Blame Contribute Delete
2.83 kB
"""Two-agent orchestrator.
Provides the per-turn coordination helpers. `app.py` calls these in order:
1. `run_manager(...)` — blocking ~2-4s, returns ManagerVerdict
2. `build_main_messages(...)` — pure, returns (messages, plan_control_text)
3. `main_agent.stream(messages)` — generator; the host threads it with its
UI animation pattern
The result of each turn (verdict + bot response + plan_control) is
assembled by app.py into a per-turn record for the session log.
"""
from dataclasses import dataclass, asdict
from core import manager_agent, main_agent
from core.manager_agent import ManagerVerdict
from core.main_agent import BotResponse
@dataclass
class TurnResult:
"""Per-turn record assembled by the host. Self-contained: holds the
manager's verdict, the verbatim PLAN CONTROL text injected, the bot's
response, and timing. Written into the session log as one turn row."""
verdict: ManagerVerdict
plan_control_text: str
bot_response: BotResponse
def to_dict(self):
return {
"manager_verdict": self.verdict.to_dict(),
"plan_control": self.plan_control_text,
"bot": {
"visible": self.bot_response.visible,
"scratch": self.bot_response.scratch,
"latency_ms": self.bot_response.latency_ms,
"ttft_ms": self.bot_response.ttft_ms,
},
}
def run_manager(discussion_plan_subprobes, manager_history, history, current_msg,
initial_argument="", client=None):
"""Blocking manager LLM call. Returns ManagerVerdict.
`initial_argument` is the participant's full submitted essay; passed so
the manager can always see the participant's overall stance regardless
of how many turns have scrolled past in `history`.
`client` is the per-session OpenAI client (from `config_loader.get_next_client()`).
Pass `None` to fall back to the module-level default client.
"""
return manager_agent.classify(
discussion_plan_subprobes=discussion_plan_subprobes,
manager_history=manager_history,
recent_turns=history,
current_msg=current_msg,
initial_argument=initial_argument,
client=client,
)
def build_main_messages(verdict, discussion_plan_subprobes, discussion_plan_text,
history, case_text):
"""Compose the main bot's input messages from manager verdict + state.
Returns (messages, plan_control_text)."""
plan_control_text = main_agent.build_plan_control(verdict, discussion_plan_subprobes)
messages = main_agent.build_messages(
history=history,
case_text=case_text,
discussion_plan_text=discussion_plan_text,
plan_control_text=plan_control_text,
)
return messages, plan_control_text