yapwrap 0.0.1a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. yapwrap/__init__.py +36 -0
  2. yapwrap/agents/__init__.py +30 -0
  3. yapwrap/agents/agno.py +54 -0
  4. yapwrap/agents/callable.py +57 -0
  5. yapwrap/agents/claude.py +49 -0
  6. yapwrap/agents/crewai.py +25 -0
  7. yapwrap/agents/google_adk.py +47 -0
  8. yapwrap/agents/langgraph.py +59 -0
  9. yapwrap/agents/llamaindex.py +27 -0
  10. yapwrap/agents/microsoft_agent.py +20 -0
  11. yapwrap/agents/openai_agents.py +34 -0
  12. yapwrap/agents/pydantic_ai.py +27 -0
  13. yapwrap/agents/smolagents.py +37 -0
  14. yapwrap/core/__init__.py +27 -0
  15. yapwrap/core/audio.py +168 -0
  16. yapwrap/core/base.py +113 -0
  17. yapwrap/core/events.py +57 -0
  18. yapwrap/core/memory.py +73 -0
  19. yapwrap/core/phrases.py +89 -0
  20. yapwrap/core/protocols.py +18 -0
  21. yapwrap/core/session.py +256 -0
  22. yapwrap/core/yapwrap.py +113 -0
  23. yapwrap/stt/__init__.py +24 -0
  24. yapwrap/stt/assemblyai.py +68 -0
  25. yapwrap/stt/deepgram.py +98 -0
  26. yapwrap/stt/elevenlabs.py +63 -0
  27. yapwrap/stt/gladia.py +77 -0
  28. yapwrap/stt/google_chirp.py +66 -0
  29. yapwrap/stt/openai_realtime.py +85 -0
  30. yapwrap/stt/soniox.py +80 -0
  31. yapwrap/stt/speechmatics.py +81 -0
  32. yapwrap/transports/__init__.py +14 -0
  33. yapwrap/transports/local.py +121 -0
  34. yapwrap/transports/webrtc.py +132 -0
  35. yapwrap/transports/websocket.py +86 -0
  36. yapwrap/tts/__init__.py +28 -0
  37. yapwrap/tts/azure.py +59 -0
  38. yapwrap/tts/cartesia.py +77 -0
  39. yapwrap/tts/deepgram.py +57 -0
  40. yapwrap/tts/elevenlabs.py +69 -0
  41. yapwrap/tts/gemini.py +62 -0
  42. yapwrap/tts/hume.py +62 -0
  43. yapwrap/tts/inworld.py +58 -0
  44. yapwrap/tts/openai.py +61 -0
  45. yapwrap/tts/rime.py +64 -0
  46. yapwrap/tts/sarvam.py +71 -0
  47. yapwrap/vad/__init__.py +18 -0
  48. yapwrap/vad/cobra.py +70 -0
  49. yapwrap/vad/energy.py +55 -0
  50. yapwrap/vad/silero.py +74 -0
  51. yapwrap/vad/smart_turn.py +55 -0
  52. yapwrap/vad/webrtc.py +72 -0
  53. yapwrap-0.0.1a1.dist-info/METADATA +339 -0
  54. yapwrap-0.0.1a1.dist-info/RECORD +56 -0
  55. yapwrap-0.0.1a1.dist-info/WHEEL +4 -0
  56. yapwrap-0.0.1a1.dist-info/licenses/LICENSE +201 -0
yapwrap/__init__.py ADDED
@@ -0,0 +1,36 @@
1
+ """YapWrap: Framework-agnostic, ultra-low-latency streaming voice pipeline for AI agents."""
2
+
3
+ from yapwrap.core.base import BaseAgent, BaseSTT, BaseTTS, BaseVAD, BaseTransport
4
+ from yapwrap.core.yapwrap import YapWrap
5
+ from yapwrap.core.protocols import Transport, VAD, STT, Agent, TTS, SessionEventSink
6
+ from yapwrap.core.events import AgentEvent, SessionEvent, TranscriptEvent
7
+ from yapwrap.core.session import VoiceSession
8
+ from yapwrap.core.memory import InMemoryHistory, ConversationTurn
9
+
10
+ # Yapper is an alias for YapWrap
11
+ Yapper = YapWrap
12
+
13
+ __all__ = [
14
+ "BaseAgent",
15
+ "BaseSTT",
16
+ "BaseTTS",
17
+ "BaseVAD",
18
+ "BaseTransport",
19
+ "YapWrap",
20
+ "Yapper",
21
+ "Transport",
22
+ "VAD",
23
+ "STT",
24
+ "Agent",
25
+ "TTS",
26
+ "AgentEvent",
27
+ "SessionEvent",
28
+ "SessionEventSink",
29
+ "TranscriptEvent",
30
+ "VoiceSession",
31
+ "InMemoryHistory",
32
+ "ConversationTurn",
33
+ ]
34
+
35
+ __version__ = "0.0.1a1"
36
+
@@ -0,0 +1,30 @@
1
+ """Python Agent SDK adapters for yapwrap."""
2
+
3
+ from yapwrap.core.base import BaseAgent
4
+ from yapwrap.agents.agno import AgnoAgent
5
+ from yapwrap.agents.langgraph import LangGraphAgent
6
+ from yapwrap.agents.openai_agents import OpenAIAgentsSDKAgent
7
+ from yapwrap.agents.pydantic_ai import PydanticAIAgent
8
+ from yapwrap.agents.google_adk import GoogleADKAgent
9
+ from yapwrap.agents.claude import ClaudeAgentSDKAgent
10
+ from yapwrap.agents.crewai import CrewAIAgent
11
+ from yapwrap.agents.llamaindex import LlamaIndexAgent
12
+ from yapwrap.agents.microsoft_agent import MicrosoftAgentFrameworkAgent
13
+ from yapwrap.agents.smolagents import SmolAgentsAgent
14
+ from yapwrap.agents.callable import CallableAgent
15
+
16
+ __all__ = [
17
+ "BaseAgent",
18
+ "AgnoAgent",
19
+ "LangGraphAgent",
20
+ "OpenAIAgentsSDKAgent",
21
+ "PydanticAIAgent",
22
+ "GoogleADKAgent",
23
+ "ClaudeAgentSDKAgent",
24
+ "CrewAIAgent",
25
+ "LlamaIndexAgent",
26
+ "MicrosoftAgentFrameworkAgent",
27
+ "SmolAgentsAgent",
28
+ "CallableAgent",
29
+ ]
30
+
yapwrap/agents/agno.py ADDED
@@ -0,0 +1,54 @@
1
+ """Agno Agent adapter for yapwrap."""
2
+
3
+ import asyncio
4
+ import inspect
5
+ from typing import Any, AsyncIterator
6
+
7
+ from yapwrap.core.base import BaseAgent
8
+ from yapwrap.core.events import AgentEvent
9
+
10
+
11
+ class AgnoAgent(BaseAgent):
12
+ """Adapts an Agno Agent into a yapwrap Agent."""
13
+
14
+ def __init__(self, agent: Any, **run_kwargs: Any) -> None:
15
+ self.agent = agent
16
+ self.run_kwargs = run_kwargs
17
+
18
+ async def respond(self, text: str) -> AsyncIterator[AgentEvent]:
19
+ """Stream events from an Agno agent run."""
20
+ # Agno agents support async streaming with stream=True
21
+ if hasattr(self.agent, "arun"):
22
+ stream = self.agent.arun(text, **{**self.run_kwargs, "stream": True, "stream_events": True})
23
+ if inspect.isawaitable(stream):
24
+ stream = await stream
25
+ try:
26
+ async for event in stream:
27
+ kind = getattr(event, "event", "")
28
+ content = getattr(event, "content", None)
29
+
30
+ if kind == "RunContent" and isinstance(content, str):
31
+ yield AgentEvent.text(content)
32
+ elif kind in ("ToolCallStarted", "ToolCallCompleted"):
33
+ tool = getattr(event, "tool", None)
34
+ name = getattr(tool, "tool_name", "tool")
35
+ if kind == "ToolCallStarted":
36
+ yield AgentEvent.tool_start(name, getattr(tool, "tool_args", None))
37
+ else:
38
+ yield AgentEvent.tool_end(name, getattr(tool, "result", None))
39
+ elif kind in ("RunError", "RunCancelled"):
40
+ raise RuntimeError(f"Agno {kind}: {content or ''}")
41
+ elif isinstance(content, str) and content and not kind:
42
+ yield AgentEvent.text(content)
43
+ finally:
44
+ close = getattr(stream, "aclose", None)
45
+ if close is not None:
46
+ await close()
47
+ elif hasattr(self.agent, "run"):
48
+ # Synchronous fallback
49
+ resp = await asyncio.to_thread(self.agent.run, text, **self.run_kwargs)
50
+ content = getattr(resp, "content", str(resp))
51
+ yield AgentEvent.text(content)
52
+ else:
53
+ raise TypeError("AgnoAgent expects an object with arun() or run()")
54
+
@@ -0,0 +1,57 @@
1
+ """Adapt plain Python callables without importing an agent framework."""
2
+
3
+ import asyncio
4
+ import inspect
5
+ from collections.abc import AsyncIterable, Iterable
6
+ from typing import Any, AsyncIterator, Callable
7
+
8
+ from yapwrap.core.base import BaseAgent
9
+ from yapwrap.core.events import AgentEvent
10
+
11
+
12
+ class CallableAgent(BaseAgent):
13
+ """Accept text, events, and synchronous or asynchronous streams of either.
14
+
15
+ Async callables are preferred for cancellable network work. Synchronous
16
+ callables run in a worker thread; Python cannot interrupt that thread.
17
+ """
18
+
19
+ def __init__(self, func: Callable[[str], Any]) -> None:
20
+ self.func = func
21
+
22
+ async def respond(self, text: str) -> AsyncIterator[AgentEvent]:
23
+ if inspect.iscoroutinefunction(self.func) or inspect.isasyncgenfunction(self.func):
24
+ result = self.func(text)
25
+ else:
26
+ result = await asyncio.to_thread(self.func, text)
27
+ if inspect.isawaitable(result):
28
+ result = await result
29
+ if isinstance(result, (str, AgentEvent)):
30
+ yield self._event(result)
31
+ elif isinstance(result, AsyncIterable):
32
+ stream = result.__aiter__()
33
+ try:
34
+ async for item in stream:
35
+ yield self._event(item)
36
+ finally:
37
+ close = getattr(stream, "aclose", None)
38
+ if close is not None:
39
+ await close()
40
+ elif isinstance(result, Iterable):
41
+ iterator = iter(result)
42
+ end = object()
43
+ while True:
44
+ item = await asyncio.to_thread(next, iterator, end)
45
+ if item is end:
46
+ break
47
+ yield self._event(item)
48
+ else:
49
+ raise TypeError("CallableAgent must return text, AgentEvent, or an iterable of either")
50
+
51
+ @staticmethod
52
+ def _event(item: Any) -> AgentEvent:
53
+ if isinstance(item, AgentEvent):
54
+ return item
55
+ if isinstance(item, str):
56
+ return AgentEvent.text(item)
57
+ raise TypeError("Agent stream items must be strings or AgentEvent objects")
@@ -0,0 +1,49 @@
1
+ """Claude Agent SDK client adapter."""
2
+
3
+ from contextlib import aclosing
4
+ from typing import Any, AsyncIterator
5
+ from yapwrap.core.base import BaseAgent
6
+ from yapwrap.core.events import AgentEvent
7
+
8
+
9
+ class ClaudeAgentSDKAgent(BaseAgent):
10
+ """Adapt a connected ClaudeSDKClient owned by an async context manager."""
11
+
12
+ def __init__(self, agent: Any) -> None:
13
+ self.agent = agent
14
+
15
+ async def respond(self, text: str) -> AsyncIterator[AgentEvent]:
16
+ await self.agent.query(text)
17
+ finished = False
18
+ partial = False
19
+ try:
20
+ async with aclosing(self.agent.receive_response()) as stream:
21
+ async for message in stream:
22
+ kind = type(message).__name__
23
+ if kind == "StreamEvent":
24
+ event = message.event
25
+ if event.get("type") == "message_start":
26
+ partial = False
27
+ delta = event.get("delta", {})
28
+ if delta.get("type") == "text_delta":
29
+ partial = True
30
+ if delta.get("text"):
31
+ yield AgentEvent.text(delta["text"])
32
+ elif kind == "AssistantMessage":
33
+ if not partial:
34
+ for block in message.content:
35
+ if type(block).__name__ == "TextBlock" and block.text:
36
+ yield AgentEvent.text(block.text)
37
+ partial = False
38
+ elif kind == "ResultMessage":
39
+ finished = True
40
+ if message.is_error:
41
+ raise RuntimeError(message.result or "Claude agent run failed")
42
+ finished = True
43
+ finally:
44
+ if not finished:
45
+ await self.agent.interrupt()
46
+ # Drain the interrupted run before the next query.
47
+ async for _ in self.agent.receive_response():
48
+ pass
49
+
@@ -0,0 +1,25 @@
1
+ """CrewAI Crew adapter."""
2
+
3
+ import asyncio
4
+ from typing import Any, AsyncIterator
5
+ from yapwrap.core.base import BaseAgent
6
+ from yapwrap.core.events import AgentEvent
7
+
8
+
9
+ class CrewAIAgent(BaseAgent):
10
+ """Speak a Crew's final output. Tasks receive the utterance as {input}."""
11
+
12
+ def __init__(self, crew_or_agent: Any) -> None:
13
+ self.crew = crew_or_agent
14
+
15
+ async def respond(self, text: str) -> AsyncIterator[AgentEvent]:
16
+ inputs = {"input": text}
17
+ if hasattr(self.crew, "akickoff"):
18
+ result = await self.crew.akickoff(inputs=inputs)
19
+ elif hasattr(self.crew, "kickoff_async"):
20
+ result = await self.crew.kickoff_async(inputs=inputs)
21
+ else:
22
+ result = await asyncio.to_thread(self.crew.kickoff, inputs=inputs)
23
+ if result.raw:
24
+ yield AgentEvent.text(result.raw)
25
+
@@ -0,0 +1,47 @@
1
+ """Google ADK Runner adapter."""
2
+
3
+ from contextlib import aclosing
4
+ from typing import Any, AsyncIterator
5
+ from yapwrap.core.base import BaseAgent
6
+ from yapwrap.core.events import AgentEvent
7
+
8
+
9
+ class GoogleADKAgent(BaseAgent):
10
+ """Adapt a Runner and an existing ADK session, owned by the application."""
11
+
12
+ def __init__(self, runner: Any, *, user_id: str, session_id: str, run_config: Any = None) -> None:
13
+ self.runner = runner
14
+ self.user_id = user_id
15
+ self.session_id = session_id
16
+ self.run_config = run_config
17
+
18
+ async def respond(self, text: str) -> AsyncIterator[AgentEvent]:
19
+ from google.genai import types
20
+
21
+ message = types.Content(role="user", parts=[types.Part(text=text)])
22
+ stream = self.runner.run_async(
23
+ user_id=self.user_id, session_id=self.session_id,
24
+ new_message=message, run_config=self.run_config,
25
+ )
26
+ partial = False
27
+ async with aclosing(stream):
28
+ async for event in stream:
29
+ if getattr(event, "error_code", None):
30
+ raise RuntimeError(event.error_message or event.error_code)
31
+ content = getattr(event, "content", None)
32
+ if content is None or content.role == "user":
33
+ continue
34
+ output = "".join(
35
+ part.text for part in (content.parts or [])
36
+ if part.text and not getattr(part, "thought", False)
37
+ )
38
+ if event.partial:
39
+ partial = True
40
+ if output:
41
+ yield AgentEvent.text(output)
42
+ else:
43
+ # ADK emits an aggregate after partial tokens of each response.
44
+ if output and not partial:
45
+ yield AgentEvent.text(output)
46
+ partial = False
47
+
@@ -0,0 +1,59 @@
1
+ """LangGraph and LangChain create_agent adapter."""
2
+
3
+ from contextlib import aclosing
4
+ from typing import Any, AsyncIterator
5
+ from yapwrap.core.base import BaseAgent
6
+ from yapwrap.core.events import AgentEvent
7
+
8
+
9
+ def _text(content: Any) -> str:
10
+ if isinstance(content, str):
11
+ return content
12
+ if isinstance(content, list):
13
+ return "".join(
14
+ block if isinstance(block, str) else block.get("text", "")
15
+ for block in content
16
+ if isinstance(block, str) or isinstance(block, dict) and block.get("type") == "text"
17
+ )
18
+ return ""
19
+
20
+
21
+ class LangGraphAgent(BaseAgent):
22
+ """Adapt a compiled graph, optionally passing config (e.g. thread_id)."""
23
+
24
+ def __init__(self, graph: Any, **run_kwargs: Any) -> None:
25
+ self.graph = graph
26
+ self.run_kwargs = run_kwargs
27
+
28
+ async def respond(self, text: str) -> AsyncIterator[AgentEvent]:
29
+ inputs = {"messages": [{"role": "user", "content": text}]}
30
+ if hasattr(self.graph, "astream_events"):
31
+ stream = self.graph.astream_events(inputs, **{**self.run_kwargs, "version": "v2"})
32
+ async with aclosing(stream):
33
+ async for event in stream:
34
+ kind, data = event.get("event"), event.get("data", {})
35
+ if kind == "on_chat_model_stream":
36
+ content = _text(getattr(data.get("chunk"), "content", ""))
37
+ if content:
38
+ yield AgentEvent.text(content)
39
+ elif kind == "on_tool_start":
40
+ yield AgentEvent.tool_start(event.get("name", "tool"), data.get("input"))
41
+ elif kind == "on_tool_end":
42
+ yield AgentEvent.tool_end(event.get("name", "tool"), data.get("output"))
43
+ return # Never execute tools again as a fallback after an error.
44
+
45
+ async with aclosing(self.graph.astream(inputs, **self.run_kwargs)) as stream:
46
+ async for chunk in stream:
47
+ if isinstance(chunk, str):
48
+ yield AgentEvent.text(chunk)
49
+ continue
50
+ states = [chunk] if "messages" in chunk else chunk.values()
51
+ for state in states:
52
+ if not isinstance(state, dict):
53
+ continue
54
+ for message in state.get("messages", []):
55
+ role = message.get("role") if isinstance(message, dict) else getattr(message, "type", None)
56
+ if role in ("assistant", "ai"):
57
+ content = _text(message.get("content") if isinstance(message, dict) else message.content)
58
+ if content:
59
+ yield AgentEvent.text(content)
@@ -0,0 +1,27 @@
1
+ """LlamaIndex FunctionAgent / AgentWorkflow adapter."""
2
+
3
+ from typing import Any, AsyncIterator
4
+ from yapwrap.core.base import BaseAgent
5
+ from yapwrap.core.events import AgentEvent
6
+
7
+
8
+ class LlamaIndexAgent(BaseAgent):
9
+ """Adapt a workflow; pass ctx=Context(agent) to retain conversation state."""
10
+
11
+ def __init__(self, agent: Any, **run_kwargs: Any) -> None:
12
+ self.agent = agent
13
+ self.run_kwargs = run_kwargs
14
+
15
+ async def respond(self, text: str) -> AsyncIterator[AgentEvent]:
16
+ handler = self.agent.run(user_msg=text, **self.run_kwargs)
17
+ finished = False
18
+ try:
19
+ async for event in handler.stream_events():
20
+ if type(event).__name__ == "AgentStream" and event.delta:
21
+ yield AgentEvent.text(event.delta)
22
+ await handler # Surface failures without repeating the final text.
23
+ finished = True
24
+ finally:
25
+ if not finished:
26
+ await handler.cancel_run()
27
+
@@ -0,0 +1,20 @@
1
+ """Microsoft Agent Framework adapter."""
2
+
3
+ from typing import Any, AsyncIterator
4
+ from yapwrap.core.base import BaseAgent
5
+ from yapwrap.core.events import AgentEvent
6
+
7
+
8
+ class MicrosoftAgentFrameworkAgent(BaseAgent):
9
+ """Adapt an Agent's ResponseStream, closing it when speech is interrupted."""
10
+
11
+ def __init__(self, agent: Any, **run_kwargs: Any) -> None:
12
+ self.agent = agent
13
+ self.run_kwargs = run_kwargs
14
+
15
+ async def respond(self, text: str) -> AsyncIterator[AgentEvent]:
16
+ async with self.agent.run(text, **{**self.run_kwargs, "stream": True}) as stream:
17
+ async for update in stream:
18
+ if update.text:
19
+ yield AgentEvent.text(update.text)
20
+
@@ -0,0 +1,34 @@
1
+ """OpenAI Agents SDK adapter; the SDK is an optional dependency."""
2
+
3
+ from contextlib import aclosing
4
+ from typing import Any, AsyncIterator
5
+ from yapwrap.core.base import BaseAgent
6
+ from yapwrap.core.events import AgentEvent
7
+
8
+
9
+ class OpenAIAgentsSDKAgent(BaseAgent):
10
+ """Adapt an SDK Agent, with optional Runner and run options (e.g. session)."""
11
+
12
+ def __init__(self, agent: Any, runner: Any = None, **run_kwargs: Any) -> None:
13
+ self.agent = agent
14
+ self.runner = runner
15
+ self.run_kwargs = run_kwargs
16
+
17
+ async def respond(self, text: str) -> AsyncIterator[AgentEvent]:
18
+ runner = self.runner
19
+ if runner is None:
20
+ from agents import Runner
21
+ runner = Runner
22
+ result = runner.run_streamed(self.agent, input=text, **self.run_kwargs)
23
+ finished = False
24
+ try:
25
+ async with aclosing(result.stream_events()) as stream:
26
+ async for event in stream:
27
+ if event.type == "raw_response_event" and event.data.type == "response.output_text.delta":
28
+ if event.data.delta:
29
+ yield AgentEvent.text(event.data.delta)
30
+ finished = True
31
+ finally:
32
+ if not finished:
33
+ result.cancel()
34
+
@@ -0,0 +1,27 @@
1
+ """Pydantic AI text agent adapter."""
2
+
3
+ from typing import Any, AsyncIterator
4
+ from yapwrap.core.base import BaseAgent
5
+ from yapwrap.core.events import AgentEvent
6
+
7
+
8
+ class PydanticAIAgent(BaseAgent):
9
+ """Adapt a text-output Agent; pass dependencies/history as run options."""
10
+
11
+ def __init__(self, agent: Any, **run_kwargs: Any) -> None:
12
+ self.agent = agent
13
+ self.run_kwargs = run_kwargs
14
+
15
+ async def respond(self, text: str) -> AsyncIterator[AgentEvent]:
16
+ if hasattr(self.agent, "run_stream"):
17
+ async with self.agent.run_stream(text, **self.run_kwargs) as result:
18
+ async for delta in result.stream_text(delta=True):
19
+ if delta:
20
+ yield AgentEvent.text(delta)
21
+ else:
22
+ result = await self.agent.run(text, **self.run_kwargs)
23
+ if not isinstance(result.output, str):
24
+ raise TypeError("PydanticAIAgent requires a text-output agent")
25
+ if result.output:
26
+ yield AgentEvent.text(result.output)
27
+
@@ -0,0 +1,37 @@
1
+ """Hugging Face smolagents adapter."""
2
+
3
+ import asyncio
4
+ from typing import Any, AsyncIterator
5
+ from yapwrap.core.base import BaseAgent
6
+ from yapwrap.core.events import AgentEvent
7
+
8
+
9
+ class SmolAgentsAgent(BaseAgent):
10
+ """Speak final answers without reading intermediate reasoning/tool logs.
11
+
12
+ Synchronous agent work runs in a worker thread. A running thread cannot be
13
+ forcibly cancelled; the next turn waits for it to finish before reusing it.
14
+ """
15
+
16
+ def __init__(self, agent: Any) -> None:
17
+ self.agent = agent
18
+ self._pending: Any = None
19
+
20
+ async def respond(self, text: str) -> AsyncIterator[AgentEvent]:
21
+ if self._pending is not None:
22
+ try:
23
+ await asyncio.shield(self._pending)
24
+ finally:
25
+ if self._pending.done():
26
+ self._pending = None
27
+ self._pending = asyncio.create_task(asyncio.to_thread(self.agent.run, text))
28
+ # Retrieve exceptions even if the session ends during the worker.
29
+ self._pending.add_done_callback(lambda task: task.exception() if not task.cancelled() else None)
30
+ try:
31
+ result = await asyncio.shield(self._pending)
32
+ if result is not None:
33
+ yield AgentEvent.text(str(result))
34
+ finally:
35
+ if self._pending.done():
36
+ self._pending = None
37
+
@@ -0,0 +1,27 @@
1
+ """YapWrap core architecture: base classes, events, audio processing, memory, and session pipeline."""
2
+
3
+ from yapwrap.core.base import BaseAgent, BaseSTT, BaseTTS, BaseVAD, BaseTransport
4
+ from yapwrap.core.protocols import Transport, VAD, STT, Agent, TTS
5
+ from yapwrap.core.events import AgentEvent, SessionEvent, TranscriptEvent
6
+ from yapwrap.core.memory import InMemoryHistory, ConversationTurn
7
+ from yapwrap.core.session import VoiceSession
8
+
9
+ __all__ = [
10
+ "BaseAgent",
11
+ "BaseSTT",
12
+ "BaseTTS",
13
+ "BaseVAD",
14
+ "BaseTransport",
15
+ "Transport",
16
+ "VAD",
17
+ "STT",
18
+ "Agent",
19
+ "TTS",
20
+ "AgentEvent",
21
+ "SessionEvent",
22
+ "TranscriptEvent",
23
+ "InMemoryHistory",
24
+ "ConversationTurn",
25
+ "VoiceSession",
26
+ ]
27
+