Metadata-Version: 2.4
Name: agentum-cloud-sdk
Version: 0.1.406
Summary: Типизированный async-клиент Agentum Cloud (/v1): загрузка документов, поиск и RAG-вопросы по вашим файлам.
Project-URL: Homepage, https://cloud.agentums.ru
Project-URL: Repository, https://gitlab.basis-pro.tech/agentum-systems/agentum-cloud
Author: Agentum Systems
License-Expression: MIT
License-File: LICENSE
Keywords: agentum,ai,async,documents,httpx,llm,rag,search
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.13
Requires-Dist: httpx>=0.27
Description-Content-Type: text/markdown

# agentum-cloud-sdk

Типизированный **async**-клиент для [Agentum Cloud](https://cloud.agentums.ru) — облака
ваших документов с поиском и ответами на естественном языке (RAG). Загружаете файлы
(PDF, DOCX, изображения, аудио), а затем ищете по ним и задаёте вопросы — ИИ отвечает
с ссылками на источники.

Тонкая обёртка над `httpx` поверх REST `/v1`. Полные type hints, `py.typed`.

## Установка

```bash
pip install agentum-cloud-sdk
```

Обновление до свежей версии: `pip install -U agentum-cloud-sdk`.

Требуется Python 3.13+.

## Токен

1. Войдите в приложение [cloud.agentums.ru](https://cloud.agentums.ru) (через Яндекс).
2. **Настройки → API-токены → Создать** — скопируйте токен `ak_…` (показывается один раз).

Токен привязан к вашему аккаунту и подписке. Держите его в секрете (как пароль);
если скомпрометирован — отзовите в настройках и создайте новый.

## Быстрый старт

```python
import asyncio
from agentum_cloud import AgentumClient


async def main() -> None:
    async with AgentumClient(
        base_url="https://api.cloud.agentums.ru",
        api_key="ak_ваш_токен",
    ) as cloud:
        # Загрузить документ
        with open("contract.pdf", "rb") as f:
            obj = await cloud.upload("contract.pdf", f.read())

        # Дождаться, пока документ проиндексируется
        await cloud.wait_until_ready(obj.id)

        # Спросить — ответ с цитатами из ваших файлов
        answer = await cloud.ask("Какой срок действия договора?")
        print(answer.answer)
        if answer.primary:  # закреплённый главный файл под запрос («найди X» → вот он)
            print(f"  главный файл: {answer.primary.filename}")
        for c in answer.citations:
            print(f"  источник: {c.filename}")


asyncio.run(main())
```

## Агентный режим (стрим)

`agent_chat` возвращает поток событий: агент сам решает, какими инструментами
воспользоваться (поиск, конвертация, перевод, сборка PDF), и по пути шлёт токены ответа.

```python
from contextlib import aclosing

from agentum_cloud import AgentumClient


async def main() -> None:
    async with AgentumClient(base_url="https://api.cloud.agentums.ru", api_key="ak_…") as cloud:
        # aclosing обязателен: только он закроет HTTP-ответ, если выйти из цикла через break
        async with aclosing(cloud.agent_chat("собери все счета за июнь в один PDF")) as stream:
            async for ev in stream:
                if ev.type == "token":
                    print(ev.delta, end="", flush=True)
                elif ev.type == "tool_start":
                    print(f"\n[{ev.name}]")
                elif ev.type == "paused":
                    # Опасное действие ждёт подтверждения — стрим на этом закончился
                    await confirm(cloud, ev)
                    break
```

Форма стрима — два правила, которые легко нарушить:

- **`paused` — конец стрима.** События `done` не будет: агент упёрся в опасный инструмент
  (удаление, перезапись файла) и ждёт решения. Продолжают ран через `agent_continue`,
  передавая решения по **всем** инструментам из события одним вызовом — не упомянутый
  инструмент молча не выполнится.
- **`error` — не конец стрима.** Кадр с ошибкой не прерывает ран: за ним могут прийти ещё
  токены и `done`. Выходить из цикла по `error` — потерять хвост ответа.

```python
async def confirm(cloud, ev) -> None:
    decisions = [(t.tool_call_id, input(f"{t.name} {t.args}? [y/n] ") == "y") for t in ev.tools]
    async with aclosing(
        cloud.agent_continue(run_id=ev.run_id, session_id=ev.session_id, decisions=decisions)
    ) as stream:
        async for ev in stream:
            if ev.type == "token":
                print(ev.delta, end="", flush=True)
```

`session_id` из `start`/`done` продолжает диалог: `agent_chat(..., session_id=sid)`. История
доступна через `list_chats()` / `get_chat(id)`; у агентных сессий `kind == "agent"`, и их `id`
можно передать обратно в `agent_chat` как `session_id`.

## Что умеет

| Метод | Назначение |
|-------|-----------|
| `upload(filename, data)` | загрузить документ/изображение/аудио |
| `wait_until_ready(object_id)` | дождаться окончания индексации |
| `list_objects(...)` / `get_object(id)` | список / детали файла (заголовок, summary, теги) |
| `get_summary(id)` | карточка содержания (метаданные обогащения) |
| `get_content(id)` | временная ссылка на оригинал (presigned URL) |
| `search(q)` | гибридный поиск (вектор + полнотекст + имя/расширение) по вашим файлам |
| `ask(query)` | ответ ИИ по вашим документам + цитаты и закреплённый файл (`primary`) |
| `translate(id, target_lang)` | перевести документ → новый объект |
| `transcribe(filename, data)` | расшифровка аудио в текст |
| `get_usage(days=...)` | расход (₽) и разбивка по статьям |
| `get_usage_history(days=...)` | дневной ряд расхода (₽ + токены + вызовы) для графика |
| `list_collections()` / `create_collection(...)` / `move_object(...)` | папки и раскладка файлов |
| `delete_object(id)` | удалить файл |
| `agent_chat(query)` / `agent_continue(...)` | агентный режим: стрим токенов и вызовов инструментов |
| `agent_status()` | доступен ли агентный режим и память |
| `list_chats()` / `get_chat(id)` / `delete_chat(id)` | история диалогов |
| `list_agent_memory()` / `clear_agent_memory()` | что агент запомнил о вас |

Все методы — корутины, кроме `agent_chat`/`agent_continue`: они возвращают асинхронный
генератор, так что `await` не нужен — сразу `async for` (внутри `aclosing`).
Клиент — async-context-manager (`async with`).

## Заметки

- Данные изолированы по аккаунту: токен видит только файлы вашего аккаунта. Файлы,
  загруженные через [Telegram-бота](https://cloud.agentums.ru), доступны здесь же после
  привязки бота к аккаунту.
- Базовый URL прода — `https://api.cloud.agentums.ru`.

## Лицензия

MIT — см. [LICENSE](LICENSE).
