Add outbound agent response boundary
This commit is contained in:
@@ -13,10 +13,12 @@ from app.agent.modes.steward import StewardMode
|
||||
from app.agent.modes.warden import WardenMode
|
||||
from app.agent.modes.librarian import LibrarianMode
|
||||
from app.agent.modes.scribe import ScribeMode
|
||||
from app.config import settings
|
||||
from app.llm.client import LLMClient
|
||||
from app.memory.database import get_session
|
||||
from app.memory.models import AgentActionType
|
||||
from app.memory.repository import Repository
|
||||
from app.twitch.chat import send_chat_message
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -212,6 +214,49 @@ class AgentOrchestrator:
|
||||
"actions_taken": actions,
|
||||
}
|
||||
|
||||
async def emit_agent_response(
|
||||
self,
|
||||
session_id: str,
|
||||
message: str,
|
||||
mode: str,
|
||||
triggered_by_message_id: str | None = None,
|
||||
) -> dict:
|
||||
"""Send an agent response through the outbound chat boundary."""
|
||||
session_info = self.active_sessions.get(session_id)
|
||||
if not session_info:
|
||||
logger.warning(f"Session {session_id} not found")
|
||||
return {"sent": False, "reason": "session_not_found"}
|
||||
|
||||
channel_name = session_info["channel_name"]
|
||||
sent = await send_chat_message(channel_name=channel_name, message=message)
|
||||
bot_username = settings.TWITCH_BOT_USERNAME or "sanctum_chronicler"
|
||||
|
||||
async for db_session in get_session():
|
||||
repo = Repository(db_session)
|
||||
bot_message_id = await repo.add_chat_message(
|
||||
session_id=session_id,
|
||||
username=bot_username,
|
||||
content=message,
|
||||
is_bot=True,
|
||||
)
|
||||
action_id = await repo.record_action(
|
||||
session_id=session_id,
|
||||
action_type=AgentActionType.RESPONSE,
|
||||
mode=mode,
|
||||
description=message,
|
||||
triggered_by_message_id=triggered_by_message_id,
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Agent response emitted. Session: {session_id}, Mode: {mode}, Sent: {sent}"
|
||||
)
|
||||
return {
|
||||
"sent": sent,
|
||||
"channel": channel_name,
|
||||
"message_id": bot_message_id,
|
||||
"action_id": action_id,
|
||||
}
|
||||
|
||||
def set_loop_interval(self, interval_seconds: float) -> None:
|
||||
"""Update how frequently the background agent loop runs."""
|
||||
if interval_seconds < 1:
|
||||
@@ -269,20 +314,17 @@ class AgentOrchestrator:
|
||||
theme=session_info.get("theme")
|
||||
)
|
||||
session_info["last_hearthkeeper_prompt_at"] = datetime.utcnow()
|
||||
|
||||
async for db_session in get_session():
|
||||
repo = Repository(db_session)
|
||||
await repo.record_action(
|
||||
session_id=session_id,
|
||||
action_type=AgentActionType.RESPONSE,
|
||||
mode="hearthkeeper",
|
||||
description=agent_response,
|
||||
)
|
||||
delivery = await self.emit_agent_response(
|
||||
session_id=session_id,
|
||||
message=agent_response,
|
||||
mode="hearthkeeper",
|
||||
)
|
||||
|
||||
return {
|
||||
"session_id": session_id,
|
||||
"actions_taken": ["HEARTHKEEPER_PROMPT"],
|
||||
"agent_response": agent_response,
|
||||
"delivery": delivery,
|
||||
"reason": "inactive_chat",
|
||||
}
|
||||
except Exception as e:
|
||||
|
||||
25
app/main.py
25
app/main.py
@@ -128,6 +128,31 @@ async def test_message(session_id: str = Form(...), message: str = Form(...), us
|
||||
}
|
||||
|
||||
|
||||
@app.post("/admin/test-agent-response")
|
||||
async def test_agent_response(
|
||||
session_id: str = Form(...),
|
||||
message: str = Form(...),
|
||||
mode: str = Form("admin"),
|
||||
) -> dict:
|
||||
"""Send a test agent response through the outbound boundary."""
|
||||
if not orchestrator:
|
||||
raise HTTPException(status_code=503, detail="Orchestrator not initialized")
|
||||
|
||||
delivery = await orchestrator.emit_agent_response(
|
||||
session_id=session_id,
|
||||
message=message,
|
||||
mode=mode,
|
||||
)
|
||||
if not delivery.get("sent"):
|
||||
raise HTTPException(status_code=404, detail=delivery.get("reason", "send_failed"))
|
||||
|
||||
return {
|
||||
"status": "agent_response_emitted",
|
||||
"delivery": delivery,
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
}
|
||||
|
||||
|
||||
@app.get("/admin/ledger")
|
||||
async def get_ledger(session_id: str) -> dict:
|
||||
"""Get the markdown ledger for a session."""
|
||||
|
||||
Reference in New Issue
Block a user