#15 Файловые вложения к сообщениям от юзера #16
4 changed files with 30 additions and 4 deletions
|
|
@ -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` всегда будет актуальная рабочая версия.
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -19,6 +19,12 @@ class MsgUserMessage(BaseModel):
|
|||
"""
|
||||
Текст сообщения.
|
||||
"""
|
||||
attachments: list[str] = Field(default_factory=list)
|
||||
"""
|
||||
Список вложений (файлов) к сообщению.
|
||||
Передается путь до файла относительно /workspace .
|
||||
Файлы уже должны быть загружены в директорию.
|
||||
"""
|
||||
|
||||
|
||||
ClientMessage = TypeAdapter(Annotated[
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue