> ## Documentation Index
> Fetch the complete documentation index at: https://docs.youka.io/llms.txt
> Use this file to discover all available pages before exploring further.

# AI Agents

> Правила эксплуатации и шаблоны рабочих процессов для агентов, вызывающих Youka CLI или API

Youka спроектирован так, чтобы им управляли агенты. Каждая команда CLI возвращает машиночитаемый JSON-конверт, каждая операция записи поддерживает ключи идемпотентности, а публичный API предоставляет ту же поверхность с той же семантикой. На этой странице собраны правила эксплуатации, которые нужны автору агента перед тем, как встроить Youka в рабочий процесс.

## Get started

Если вы настраиваете агента впервые, сначала установите Youka CLI, затем установите навык Youka karaoke:

```bash theme={null}
npm install -g @youka/cli
npx skills add https://github.com/youka-io/skills --skill youka-karaoke
```

Это даст агенту готовый навык Youka, работающий поверх CLI. После установки используйте шаблоны рабочих процессов ниже, чтобы создавать караоке-видео, настраивать стиль и безопасно экспортировать MP4-файлы.

### Prompt your agent

После установки CLI и навыка вы можете дать агенту прямую задачу, например так:

<CodeGroup>
  ```text local-file theme={null}
  Используй Youka, чтобы создать караоке-видео из /path/to/song.mp3. Транскрибируй текст песни на английском, используй чистый стиль караоке-субтитров, экспортируй финальное видео в 1080p и сохрани как ./karaoke.mp4.
  ```

  ```text url theme={null}
  Используй Youka, чтобы создать караоке-видео из https://example.com/song.mp4. Если зависимости для URL отсутствуют — сначала установи их. Затем автоматически транскрибируй текст песни, используй чистый стиль караоке-субтитров, экспортируй финальное видео и сохрани как ./karaoke.mp4.
  ```
</CodeGroup>

## Operating rules

<CardGroup cols={2}>
  <Card title="Always use --json" icon="code">
    В CLI всегда передавайте `--json`. В API всегда устанавливайте `Accept:
            application/json`. Никогда не парсите человекочитаемый вывод.
  </Card>

  <Card title="Always send an idempotency key" icon="rotate">
    Каждая операция записи должна содержать стабильный ключ идемпотентности, чтобы повтор после таймаута возвращал исходный результат вместо дублирования работы.
  </Card>

  <Card title="Re-read durable state" icon="database">
    Не доверяйте устаревшим ответам на мутации. После завершения задачи перечитайте проект или экспорт, чтобы получить финальное состояние.
  </Card>

  <Card title="Poll with backoff" icon="hourglass">
    Начинайте с интервала 2–3 секунды. Экспоненциально увеличивайте интервал для длительных задач.
    Учитывайте ответы 429.
  </Card>
</CardGroup>

## Output contract

Каждая команда CLI в режиме `--json` пишет ровно один конверт в stdout.

Успех:

```json theme={null}
{
  "schemaVersion": "1",
  "ok": true,
  "data": { "id": "prj_abc123", "title": "My Song" }
}
```

Ошибка:

```json theme={null}
{
  "schemaVersion": "1",
  "ok": false,
  "error": {
    "code": "CONFLICT",
    "message": "A request with this Idempotency-Key is already in progress.",
    "retryable": true
  }
}
```

Коды завершения:

| Code | Meaning                                               | Retry?                       |
| ---- | ----------------------------------------------------- | ---------------------------- |
| `0`  | Успех.                                                | N/A                          |
| `1`  | Ошибка выполнения (сеть, API, рендер).                | Проверьте `error.retryable`. |
| `2`  | Некорректный ввод (плохие флаги, нечитаемый payload). | Нет — исправьте ввод.        |

## End-to-end workflow

Канонический рабочий процесс агента: создать проект, дождаться, экспортировать, скачать результат. Ниже — полный шаблон с реализациями и для CLI, и для SDK.

<CodeGroup>
  ```bash CLI theme={null}
  # 1. Create the project and wait for stems + lyrics sync to finish
  PROJECT_JSON=$(youka project create ./song.mp3 \
    --mode transcribe \
    --lang en \
    --wait \
    --idempotency-key "create-song-2026-04-08-001" \
    --json)

  PROJECT_ID=$(echo "$PROJECT_JSON" | jq -r '.data.projectId')

  # 2. Start and wait for an export
  EXPORT_JSON=$(youka export create "$PROJECT_ID" \
    --resolution 1080p \
    --quality high \
    --wait \
    --download \
    --output ./karaoke.mp4 \
    --idempotency-key "export-$PROJECT_ID-v1" \
    --json)

  echo "Done:" "$(echo "$EXPORT_JSON" | jq -r '.data.fileUrl')"
  ```

  ```ts SDK theme={null}
  import { YoukaClient, YoukaRequestError, YoukaTaskError } from "@youka/ru/sdk";

  const client = new YoukaClient({ apiKey: process.env.YOUKA_API_KEY! });

  async function createAndExport() {
    // 1. Create the project and wait for stems + lyrics sync
    const created = await client.projects.create(
      {
        source: { type: "path", path: "./song.mp3" },
        lyricsSource: { type: "transcribe", language: "en" },
      },
      { idempotencyKey: "create-song-2026-04-08-001" },
    );

    const { project } = await client.projects.wait(created);

    // 2. Start and wait for an export
    const exportResult = await client.exports.create(
      project.id,
      { resolution: "1080p", quality: "high" },
      { idempotencyKey: `export-${project.id}-v1` },
    );

    const finalized = await client.exports.wait(exportResult);

    // 3. Download the file
    await client.exports.download(finalized, {
      output: "./karaoke.mp4",
    });
  }

  createAndExport().catch((error) => {
    if (error instanceof YoukaRequestError && error.retryable) {
      // Retry with the same idempotency keys
    }
    if (error instanceof YoukaTaskError) {
      console.error("Task failed:", error.code, error.task.error);
    }
    throw error;
  });
  ```
</CodeGroup>

## Polling guidance

Большинство операций записи в SDK возвращают дескрипторы операций. Предпочитайте `client.projects.wait(...)` и `client.exports.wait(...)` и опускайтесь до `client.tasks.*` только когда вам явно нужен низкоуровневый доступ к задачам.

| Job type                                        | Recommended initial interval | Max wait |
| ----------------------------------------------- | ---------------------------- | -------- |
| Создание проекта (stems + синхронизация текста) | 3 s                          | 15 min   |
| Только разделение stems                         | 3 s                          | 10 min   |
| Только синхронизация текста                     | 2 s                          | 5 min    |
| Рендер экспорта                                 | 3 s                          | 30 min   |

В CLI флаг `--wait` делает polling за вас. В SDK wait-хелперы по умолчанию используют интервал 2 s и принимают `pollIntervalMs`.

<Tip>
  Учитывайте ответы 429. При rate limit делайте back off как минимум на значение заголовка `Retry-After`
  (или на 30 s, если его нет).
</Tip>

## Idempotency keys

Каждая операция создания и обновления поддерживает ключ идемпотентности. Правила:

* Используйте **стабильный, уникальный, детерминированный** ключ на одну логическую мутацию. Хорошо: `create-song-${sourceHash}`. Плохо: новый UUID на каждый повтор.
* При повторах используйте **тот же самый** ключ. Сервер распознаёт повтор и возвращает исходный результат.
* Ключи действуют в рамках одного аккаунта и истекают через 24 часа.
* Если сервер возвращает `IDEMPOTENT_REPLAY_IN_PROGRESS` (HTTP 202), исходный запрос всё ещё выполняется. Подождите и повторите с тем же ключом.

Пример шаблона:

```ts theme={null}
const key = `create-${sha256(sourceBytes)}`;

try {
  return await client.projects.create(body, { idempotencyKey: key });
} catch (error) {
  if (error instanceof YoukaRequestError && error.retryable) {
    // Safe to retry with the same key
    return await client.projects.create(body, { idempotencyKey: key });
  }
  throw error;
}
```

Полный контракт см. в [API idempotency](/ru/api/idempotency).

## Error recovery

Ветвитесь по `error.code` и `error.retryable`. Частые случаи:

| Code                                  | Cause                                         | Action                                                        |
| ------------------------------------- | --------------------------------------------- | ------------------------------------------------------------- |
| `INVALID_REQUEST`                     | Тело запроса не прошло валидацию схемы.       | Исправьте payload. Без повтора.                               |
| `UNAUTHORIZED`                        | Отсутствует или неверный API key.             | Передайте вызывающей стороне. Без повтора.                    |
| `NOT_FOUND`                           | Ресурс не существует или нет доступа.         | Без повтора.                                                  |
| `CONFLICT` (409)                      | Конфликт версий или коллизия идемпотентности. | Повторите с тем же ключом идемпотентности.                    |
| `TOO_MANY_REQUESTS` (429)             | Rate limit.                                   | Back off по `Retry-After` или 30 s.                           |
| `INTERNAL_SERVER_ERROR` (500)         | Временный сбой сервера.                       | Повторить до 3 раз с backoff.                                 |
| `IDEMPOTENT_REPLAY_IN_PROGRESS` (202) | Предыдущий запрос всё ещё выполняется.        | Подождать и повторить с тем же ключом.                        |
| `TASK_FAILED`                         | Асинхронная задача завершилась неуспехом.     | Передайте `error.task.error` вызывающей стороне. Без повтора. |
| `TASK_TIMED_OUT`                      | Асинхронная задача превысила лимит времени.   | Можно безопасно повторить один раз.                           |

## Discovering mutable fields

Перед изменением пресетов запросите схему пресета, чтобы модель знала допустимые поля и типы значений:

<CodeGroup>
  ```bash CLI theme={null}
  # Preset body schema
  youka preset schema --json
  ```

  ```ts SDK theme={null}
  import { KaraokePresetSchema } from "@youka/ru/sdk";

  const presetSchema = KaraokePresetSchema.toJSONSchema();
  ```
</CodeGroup>

Для настроек проекта предпочтительно сначала читать текущие настройки проекта, а затем отправлять минимальное тело обновления через `youka project settings <id> --body ...`.

Запрашивайте один раз на сессию агента и кэшируйте результат.

## Parallel agents

Когда несколько агентов работают параллельно в рамках одного аккаунта:

* Делайте idempotency keys привязанными **и** к идентичности агента, **и** к логической мутации: `agent-${agentId}-create-${sourceHash}`. Это предотвращает коллизию повтора одного агента с новым запросом другого.
* Оставляйте чтения неограниченными — `GET`-запросы дешёвые и не имеют побочных эффектов.
* Используйте одну очередь для `POST /projects/{projectId}/exports` на проект, если вам нужна упорядоченная история экспортов. Иначе экспорты могут приходить не по порядку.

## What's next

* [CLI global options](/ru/cli/global-options) — все флаги, доступные агентам
* [SDK errors](/ru/sdk/errors) — полный справочник классов ошибок
* [API async jobs](/ru/api/async-jobs) — контракт polling
* [API idempotency](/ru/api/idempotency) — контракт идемпотентности
