73 lines
3.1 KiB
Python
73 lines
3.1 KiB
Python
from uuid import uuid4
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.ai.tool_registry import ToolRegistry
|
|
from app.domain.schemas import EventType, PendingActionCreate, TranscriptChunk
|
|
from app.infrastructure.database import PendingAction
|
|
from app.infrastructure.events import EventPublisher
|
|
from app.memory.context_builder import ContextBuilder
|
|
from app.memory.memory_manager import MemoryManager
|
|
from app.planner.llm_planner import HybridPlanner
|
|
from app.validation.action_validator import ActionValidator
|
|
from app.validation.policy_engine import PolicyEngine
|
|
|
|
|
|
class Orchestrator:
|
|
"""Turns transcript events into pending, validated review actions."""
|
|
|
|
def __init__(
|
|
self,
|
|
context: ContextBuilder,
|
|
memory: MemoryManager,
|
|
planner: HybridPlanner,
|
|
registry: ToolRegistry,
|
|
publisher: EventPublisher,
|
|
) -> None:
|
|
self.context = context
|
|
self.memory = memory
|
|
self.planner = planner
|
|
self.registry = registry
|
|
self.publisher = publisher
|
|
|
|
async def ingest(self, session: Session, chunk: TranscriptChunk) -> PendingAction | None:
|
|
request_id = str(uuid4())
|
|
self.context.add_chunk(chunk)
|
|
self.publisher.publish(EventType.CONVERSATION_EVENT, request_id, chunk.model_dump(mode="json"))
|
|
memories = self.memory.retrieve(chunk.text)
|
|
decision = await self.planner.plan(chunk, self.context.snapshot(), memories, self.registry.list())
|
|
self.context.add_decision(decision.model_dump())
|
|
|
|
validation = ActionValidator(self.registry).validate(decision)
|
|
existing = [row.payload for row in session.query(PendingAction).filter(PendingAction.status == "pending_review").all()]
|
|
policy = PolicyEngine(existing).evaluate(decision)
|
|
if not validation.valid or not policy.allowed:
|
|
self.publisher.publish(
|
|
EventType.ACTION_REJECTED,
|
|
request_id,
|
|
{"decision": decision.model_dump(), "validation": validation.model_dump(), "policy": policy.model_dump()},
|
|
)
|
|
return None
|
|
action_in = PendingActionCreate(
|
|
meeting_id="demo-meeting",
|
|
tool=decision.tool or "",
|
|
intent=decision.intent,
|
|
reasoning=decision.reasoning,
|
|
confidence=decision.confidence,
|
|
payload=decision.arguments,
|
|
extracted_entities=decision.extracted_entities,
|
|
validation=validation,
|
|
policy=policy,
|
|
)
|
|
row = action_in.model_dump(mode="json")
|
|
row["validation"] = validation.model_dump()
|
|
row["policy"] = policy.model_dump()
|
|
action = PendingAction(**row, status="pending_review")
|
|
session.add(action)
|
|
session.commit()
|
|
session.refresh(action)
|
|
self.memory.upsert("pending_action", f"{action.intent}: {action.payload}", {"action_id": action.id})
|
|
self.publisher.publish(EventType.ACTION_CREATED, request_id, {"action_id": action.id, "decision": decision.model_dump()})
|
|
self.publisher.publish(EventType.MEMORY_UPDATED, request_id, {"action_id": action.id, "type": "pending_action"})
|
|
return action
|