feat(core,frontends,agents): agent kinds, frontend routing, anthropic on conversations, vault mirror
This commit is contained in:
@@ -63,6 +63,7 @@ if TYPE_CHECKING:
|
||||
from beaver_gateway.core.injects import Priority
|
||||
from beaver_gateway.core.registry import AgentRegistry
|
||||
from beaver_gateway.core.sessions import SessionPool
|
||||
from beaver_gateway.frontends.base import Frontend
|
||||
from beaver_gateway.storage.db import Database
|
||||
|
||||
__all__ = [
|
||||
@@ -138,6 +139,7 @@ class Conversations:
|
||||
pool: SessionPool,
|
||||
store: SessionStore,
|
||||
texts: ConversationTexts | None = None,
|
||||
frontends: Sequence[Frontend] = (),
|
||||
normal_window: float = 3600.0,
|
||||
idle_days: Sequence[int] = (2,),
|
||||
idle_interval: float = 3600.0,
|
||||
@@ -149,6 +151,7 @@ class Conversations:
|
||||
self._pool = pool
|
||||
self._store = store
|
||||
self._texts = texts or ConversationTexts()
|
||||
self._frontends = [f for f in frontends if f.name]
|
||||
self._normal_window = normal_window
|
||||
self._idle_days = tuple(sorted(idle_days))
|
||||
self._idle_interval = idle_interval
|
||||
@@ -185,7 +188,9 @@ class Conversations:
|
||||
if kind not in KINDS:
|
||||
msg = f"unknown conversation kind {kind!r}"
|
||||
raise ValueError(msg)
|
||||
self._claude_agent(agent)
|
||||
if not self._claude_agent(agent).serves(kind):
|
||||
msg = f"agent {agent!r} does not serve kind {kind!r}"
|
||||
raise ValueError(msg)
|
||||
now = datetime.now(UTC)
|
||||
row = Conversation(
|
||||
frontend=origin,
|
||||
@@ -251,6 +256,9 @@ class Conversations:
|
||||
external_id: str,
|
||||
visible: bool = True,
|
||||
) -> ConversationBinding:
|
||||
if conv.kind not in self.frontend(frontend).kinds:
|
||||
msg = f"frontend {frontend!r} does not show kind {conv.kind!r}"
|
||||
raise ValueError(msg)
|
||||
async with self._db.session() as session:
|
||||
existing = list(
|
||||
(
|
||||
@@ -385,13 +393,41 @@ class Conversations:
|
||||
out["busy"] = live.busy if live is not None else False
|
||||
return out
|
||||
|
||||
# ---- routing -------------------------------------------------------
|
||||
|
||||
@property
|
||||
def frontends(self) -> list[Frontend]:
|
||||
return list(self._frontends)
|
||||
|
||||
def frontend(self, name: str) -> Frontend:
|
||||
for fe in self._frontends:
|
||||
if fe.name == name:
|
||||
return fe
|
||||
msg = f"unknown frontend {name!r}"
|
||||
raise ValueError(msg)
|
||||
|
||||
def default_agent(self, kind: str) -> str | None:
|
||||
for fe in self._frontends:
|
||||
if kind in fe.kinds and (agent := fe.agent_for(kind)):
|
||||
return agent
|
||||
return None
|
||||
|
||||
async def materialize(self, conv: Conversation) -> ConversationBinding | None:
|
||||
for fe in self._frontends:
|
||||
if conv.kind not in fe.kinds:
|
||||
continue
|
||||
binding = await fe.materialize(conv)
|
||||
if binding is not None:
|
||||
return binding
|
||||
return None
|
||||
|
||||
# ---- §3.1 api ------------------------------------------------------
|
||||
|
||||
async def spawn(
|
||||
self,
|
||||
*,
|
||||
kind: str,
|
||||
agent: str,
|
||||
agent: str | None = None,
|
||||
seed: str = "clean",
|
||||
parent: Conversation | None = None,
|
||||
text: str | None = None,
|
||||
@@ -405,6 +441,12 @@ class Conversations:
|
||||
if seed == "brief" and not text:
|
||||
msg = "seed=brief needs text"
|
||||
raise ValueError(msg)
|
||||
if agent is None and kind == "branch" and parent is not None:
|
||||
agent = parent.agent_name
|
||||
agent = agent or self.default_agent(kind)
|
||||
if agent is None:
|
||||
msg = f"no default agent for kind {kind!r}; pass `agent`"
|
||||
raise ValueError(msg)
|
||||
session_id: str | None = None
|
||||
if seed == "copy":
|
||||
if parent is None or parent.session_id is None:
|
||||
@@ -421,6 +463,7 @@ class Conversations:
|
||||
origin=origin,
|
||||
session_id=session_id,
|
||||
)
|
||||
await self.materialize(conv)
|
||||
prompt = await self._seed_text(
|
||||
SeedContext(
|
||||
kind=kind, seed=seed, agent=agent, parent=parent, text=text, title=title
|
||||
@@ -888,6 +931,8 @@ class Conversations:
|
||||
conversation_id=conv.external_id,
|
||||
turn_id=turn_id,
|
||||
item=head.id,
|
||||
source="queue",
|
||||
prompt=prompt,
|
||||
text=text,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user