#5 Реализовать клиентскую часть канала общения.Добавлен класс AgentApi, реализованный контекстным менеджером. Добавлен init.py для пакета api. В uv добавлена зависимость aiohttp

This commit is contained in:
Ярослав Малинин 2026-03-29 18:02:27 +03:00
parent 5f5dd3e83e
commit dab8cf6335
6 changed files with 581 additions and 15 deletions

View file

@ -10,29 +10,93 @@ pip install .
Требуется Python 3.14+.
## Быстрый старт
## Быстрый старт (с использованием AgentApi)
```python
import asyncio
from agent_api import AgentApi, OM
async def main():
# Автоматическое управление соединением через контекстный менеджер
async with AgentApi("ws://localhost:8000") as agent:
# Отправляем сообщение
await agent.send_user_message("Привет, агент!")
# Читаем ответ потоком событий
async for message in agent.listen():
if isinstance(message, OM.EventTextChunk):
print(message.text, end="", flush=True)
elif isinstance(message, OM.EventEnd):
print(f"\n[Завершено, использовано токенов: {message.tokens_used}]")
break
elif isinstance(message, OM.Error):
print(f"\n[Ошибка: {message.code}] {message.details}")
break
asyncio.run(main())
```
## AgentApi - Асинхронный Python клиент
Новая библиотека `AgentApi` предоставляет типизированный асинхронный клиент для WebSocket взаимодействия с агентом.
### Характеристики
- ✅ **Асинхронный клиент** на основе `aiohttp`
- ✅ **Контекстный менеджер** для управления соединением
- ✅ **Асинхронный генератор** `listen()` для потокового получения сообщений
- ✅ **Типизированные сообщения** через Pydantic с дискриминированными объединениями
- ✅ **Обработка ошибок** с кастомным исключением `AgentException`
- ✅ **Логирование** на всех уровнях операций
- ✅ **Полная документация** всех методов
### Использование
```python
from agent_api import AgentApi, AgentException, OM
# Использование с контекстным менеджером
async with AgentApi("ws://localhost:8000") as agent:
# Отправка сообщения
await agent.send_user_message("Your question here")
# Получение потока ответов
try:
async for message in agent.listen():
if isinstance(message, OM.Status):
print("✓ Agent is ready")
elif isinstance(message, OM.EventTextChunk):
print(message.text, end="", flush=True)
elif isinstance(message, OM.EventEnd):
print(f"\nDone! Tokens: {message.tokens_used}")
break
except AgentException as e:
print(f"Agent error ({e.code}): {e.details}")
```
## Классический подход (низкоуровневый)
```python
import asyncio
import websockets
from api.models import OutgoingMessage, OM
from models import OutgoingMessage, OM
async def main():
uri = "ws://localhost:8000/ws"
async with websockets.connect(uri) as ws:
# 1. Ждём STATUS - подтверждение готовности
status = await ws.recv()
print(f"Connected: {status}")
# 2. Отправляем сообщение
await ws.send('{"type": "USER_MESSAGE", "text": "Привет!"}')
# 3. Читаем ответ в виде потока событий
while True:
msg = await ws.recv()
data = OutgoingMessage.model_validate_json(msg)
match data:
case OM.AgentEvent(subtype=OM.AgentEventType.TEXT_CHUNK):
print(data.text, end="", flush=True)