> ## 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.

# Agentes de IA

> Regras operacionais e padrões de workflow para agentes que chamam a Youka CLI ou a API

A Youka foi projetada para ser conduzida por agentes. Todo comando da CLI retorna um envelope JSON legível por máquina, toda escrita oferece suporte a chaves de idempotência e a API pública expõe a mesma superfície com a mesma semântica. Esta página reúne as regras operacionais de que um autor de agentes precisa antes de conectar a Youka a um workflow.

## Primeiros passos

Se você estiver configurando um agente pela primeira vez, instale primeiro a Youka CLI e, em seguida, instale a skill de karaokê da Youka:

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

Isso fornece ao agente uma skill pronta da Youka apoiada na CLI. Depois de instalada, use os padrões de workflow abaixo para criar vídeos de karaokê, personalizar o estilo e exportar arquivos MP4 com segurança.

### Instrua seu agente

Após instalar a CLI e a skill, você pode dar ao seu agente uma tarefa direta como esta:

<CodeGroup>
  ```text local-file theme={null}
  Use Youka to create a karaoke video from /path/to/song.mp3. Transcribe the lyrics in English, use a clean karaoke subtitle style, export the final video in 1080p, and save it as ./karaoke.mp4.
  ```

  ```text url theme={null}
  Use Youka to create a karaoke video from https://example.com/song.mp4. If URL dependencies are missing, install them first. Then transcribe the lyrics automatically, use a clean karaoke subtitle style, export the final video, and save it as ./karaoke.mp4.
  ```
</CodeGroup>

## Regras operacionais

<CardGroup cols={2}>
  <Card title="Sempre use --json" icon="code">
    Na CLI, sempre passe `--json`. Na API, sempre defina `Accept:
            application/json`. Nunca faça parse de saída humana.
  </Card>

  <Card title="Sempre envie uma chave de idempotência" icon="rotate">
    Toda escrita deve levar uma chave de idempotência estável para que novas tentativas após um timeout
    retornem o resultado original em vez de duplicar trabalho.
  </Card>

  <Card title="Releia o estado durável" icon="database">
    Não confie em respostas de mutação desatualizadas. Após uma tarefa terminal, releia o
    projeto ou a exportação para obter o estado final.
  </Card>

  <Card title="Faça polling com backoff" icon="hourglass">
    Comece com um intervalo de 2–3 segundos. Aplique backoff exponencial para jobs longos.
    Respeite respostas 429.
  </Card>
</CardGroup>

## Contrato de saída

Todo comando da CLI no modo `--json` escreve exatamente um envelope no stdout.

Sucesso:

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

Falha:

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

Códigos de saída:

| Code | Meaning                                           | Retry?                       |
| ---- | ------------------------------------------------- | ---------------------------- |
| `0`  | Sucesso.                                          | N/A                          |
| `1`  | Erro de runtime (rede, API, renderização).        | Verifique `error.retryable`. |
| `2`  | Entrada inválida (flags ruins, payload ilegível). | Não — corrija a entrada.     |

## Workflow de ponta a ponta

O workflow canônico do agente é: criar um projeto, aguardar, exportar, baixar o resultado. Aqui está o padrão completo com implementações em CLI e 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/pt/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>

## Orientações de polling

A maioria das escritas retorna handles de operação no SDK. Prefira `client.projects.wait(...)` e `client.exports.wait(...)` e recorra a `client.tasks.*` apenas quando você precisar explicitamente de acesso a tasks de baixo nível.

| Job type                                    | Recommended initial interval | Max wait |
| ------------------------------------------- | ---------------------------- | -------- |
| Criação de projeto (stems + sync de letras) | 3 s                          | 15 min   |
| Apenas separação de stems                   | 3 s                          | 10 min   |
| Apenas sync de letras                       | 2 s                          | 5 min    |
| Render de exportação                        | 3 s                          | 30 min   |

Na CLI, `--wait` cuida do polling para você. No SDK, os helpers de wait usam um intervalo de 2 s por padrão e aceitam `pollIntervalMs`.

<Tip>
  Respeite respostas 429. Em rate limits, aplique backoff de pelo menos o header `Retry-After`
  (ou 30 s se estiver ausente).
</Tip>

## Chaves de idempotência

Toda operação de criação e atualização suporta uma chave de idempotência. Regras:

* Use uma chave **estável, única e determinística** por mutação lógica. Bom: `create-song-${sourceHash}`. Ruim: um UUID novo a cada retry.
* Reuse a **mesma** chave em novas tentativas. O servidor reconhece o replay e retorna o resultado original.
* As chaves têm escopo por conta e expiram após 24 horas.
* Se o servidor retornar `IDEMPOTENT_REPLAY_IN_PROGRESS` (HTTP 202), a requisição original ainda está em execução. Aguarde e tente novamente com a mesma chave.

Padrão de exemplo:

```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;
}
```

Veja [API idempotency](/pt/api/idempotency) para o contrato completo.

## Recuperação de erros

Faça branch com base em `error.code` e `error.retryable`. Os casos comuns:

| Code                                  | Cause                                                | Action                                             |
| ------------------------------------- | ---------------------------------------------------- | -------------------------------------------------- |
| `INVALID_REQUEST`                     | O corpo da requisição falhou na validação do schema. | Corrija o payload. Sem retry.                      |
| `UNAUTHORIZED`                        | Chave de API ausente ou inválida.                    | Exiba ao chamador. Sem retry.                      |
| `NOT_FOUND`                           | O recurso não existe ou você não tem acesso.         | Sem retry.                                         |
| `CONFLICT` (409)                      | Conflito de versão ou colisão de idempotência.       | Tente novamente com a mesma chave de idempotência. |
| `TOO_MANY_REQUESTS` (429)             | Rate limit.                                          | Aplique backoff por `Retry-After` ou 30 s.         |
| `INTERNAL_SERVER_ERROR` (500)         | Falha transitória no servidor.                       | Retry até 3 vezes com backoff.                     |
| `IDEMPOTENT_REPLAY_IN_PROGRESS` (202) | Requisição anterior ainda em execução.               | Aguarde e tente novamente com a mesma chave.       |
| `TASK_FAILED`                         | A task assíncrona terminou em falha.                 | Exiba `error.task.error` ao chamador. Sem retry.   |
| `TASK_TIMED_OUT`                      | A task assíncrona excedeu seu orçamento.             | Seguro tentar novamente uma vez.                   |

## Descobrindo campos mutáveis

Antes de mutar presets, busque o schema do preset para que o modelo conheça os campos válidos e os tipos de valor:

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

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

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

Para configurações de projeto, prefira ler primeiro as configurações atuais do projeto e, em seguida, enviar um corpo mínimo de update por meio de `youka project settings <id> --body ...`.

Busque uma vez por sessão do agente e faça cache do resultado.

## Agentes em paralelo

Quando vários agentes executam simultaneamente na mesma conta:

* Defina o escopo das chaves de idempotência para **ambos**: a identidade do agente e a mutação lógica: `agent-${agentId}-create-${sourceHash}`. Isso evita que o retry de um agente colida com a requisição nova de outro agente.
* Mantenha leituras sem limites — requisições `GET` são baratas e não têm efeitos colaterais.
* Use uma única fila para `POST /projects/{projectId}/exports` por projeto se você precisar de histórico de exportações ordenado. Caso contrário, as exportações podem chegar fora de ordem.

## Próximos passos

* [CLI global options](/pt/cli/global-options) — todas as flags disponíveis para agentes
* [SDK errors](/pt/sdk/errors) — referência completa de classes de erro
* [API async jobs](/pt/api/async-jobs) — o contrato de polling
* [API idempotency](/pt/api/idempotency) — o contrato de idempotência
