#15 Файловые вложения к сообщениям от юзера #16

Merged
mrkan merged 2 commits from #15-attachments into master 2026-04-20 10:22:38 +00:00
4 changed files with 30 additions and 4 deletions

View file

@ -9,6 +9,7 @@ WebSocket API SDK для взаимодействия с AI-агентом.
- Добавлен параметр `chat_id` в конструктор `AgentAPI`. Нужен для разделения истории сообщений по чатам/веткам.
- `AgentAPI.connect()` вызывает `AgentBusyException`, если выбранный чат уже занят другим API клиентом.
- Добавлен новый тип события `MsgEventSendFile` для отправки файлов пользователю. Поле `path` — путь к файлу относительно `/workspace`.
- `send_message(text, attachments)` теперь принимает `attachments` — список путей к файлам относительно `/workspace`.
## Установка
В `master` всегда будет актуальная рабочая версия.

View file

@ -164,11 +164,17 @@ class AgentApi:
except Exception as e:
logger.error(f"Error in on_disconnect: {e}")
async def send_message(self, text: str) -> AsyncIterator[AgentEventUnion]:
async def send_message(
self, text: str, attachments: list[str] | None = None
) -> AsyncIterator[AgentEventUnion]:
"""
Нативный асинхронный генератор.
Не требует отдельного класса ResponseIterator.
Гарантированно освобождает блокировку.
Args:
text: Текст сообщения.
attachments: Список путей к файлам относительно /workspace.
"""
if not self._connected or not self._ws:
raise AgentException(
@ -185,7 +191,11 @@ class AgentApi:
try:
self._current_queue = asyncio.Queue()
message = MsgUserMessage(type=EClientMessage.USER_MESSAGE, text=text)
message = MsgUserMessage(
type=EClientMessage.USER_MESSAGE,
text=text,
attachments=attachments or [],
)
await self._ws.send_str(message.model_dump_json())
logger.debug(f"[{self.id}] Sent message: {text[:50]}...")
@ -248,7 +258,7 @@ class AgentApi:
self._request_lock.release()
async def _listen(self):
""""
"""
Прослушивание вебсокета.
"""
try:

View file

@ -19,6 +19,12 @@ class MsgUserMessage(BaseModel):
"""
Текст сообщения.
"""
attachments: list[str] = Field(default_factory=list)
"""
Список вложений (файлов) к сообщению.
Передается путь до файла относительно /workspace .
Файлы уже должны быть загружены в директорию.
"""
ClientMessage = TypeAdapter(Annotated[

View file

@ -23,9 +23,18 @@ async def main():
while True:
try:
prompt = await asyncio.get_event_loop().run_in_executor(None, input, ">>> ")
attachments_input = await asyncio.get_event_loop().run_in_executor(
None, input, "Attachments (comma-separated, empty for none): "
)
attachments = (
[a.strip() for a in attachments_input.split(",") if a.strip()]
if attachments_input.strip()
else None
)
print("Agent: ", end="")
is_tool = False
async for chunk in api.send_message(prompt):
async for chunk in api.send_message(prompt, attachments):
match chunk:
case MsgEventTextChunk():
is_tool = False