11from __future__ import annotations
22
33import abc
4+ from dataclasses import dataclass
45import enum
56from typing import Any , AsyncIterator , Awaitable , Callable , Type
7+ import uuid
68
79from pydantic import BaseModel , Field
810
@@ -238,6 +240,26 @@ async def new_reply_topic(self) -> str:
238240 pass
239241
240242
243+ @dataclass
244+ class AgentSpec :
245+ """The specification of an agent."""
246+
247+ name : str
248+ constructor : Constructor
249+ description : str = ""
250+
251+ _runtime : Runtime | None = None
252+
253+ async def run_stream (self , msg : RawMessage ) -> AsyncIterator [RawMessage ]:
254+ if self ._runtime is None :
255+ raise ValueError (f"AgentSpec { self .name } is not registered to a runtime." )
256+
257+ addr = Address (name = self .name , id = uuid .uuid4 ().hex )
258+ result = self ._runtime .channel .publish_multi (addr , msg )
259+ async for chunk in result :
260+ yield chunk
261+
262+
241263class Runtime (abc .ABC ):
242264 async def __aenter__ (self ):
243265 await self .start ()
@@ -254,10 +276,15 @@ async def start(self) -> None:
254276 async def stop (self ) -> None :
255277 pass
256278
257- @abc .abstractmethod
258279 async def register (
259280 self , name : str , constructor : Constructor , description : str = ""
260281 ) -> None :
282+ await self .register_spec (
283+ AgentSpec (name = name , constructor = constructor , description = description )
284+ )
285+
286+ @abc .abstractmethod
287+ async def register_spec (self , spec : AgentSpec ) -> None :
261288 pass
262289
263290 @abc .abstractmethod
0 commit comments