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

# Agenti AI

> Regole operative e pattern di workflow per agenti che chiamano la Youka CLI o l’API

Youka è progettato per essere guidato da agenti. Ogni comando CLI restituisce una busta JSON leggibile dalle macchine, ogni operazione di scrittura supporta chiavi di idempotenza e l’API pubblica espone la stessa superficie con la stessa semantica. Questa pagina raccoglie le regole operative di cui un autore di agenti ha bisogno prima di integrare Youka in un workflow.

## Per iniziare

Se stai configurando un agente per la prima volta, installa prima la Youka CLI, poi installa la skill karaoke di Youka:

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

Questo fornisce all’agente una skill Youka pronta all’uso, basata sulla CLI. Una volta installata, usa i pattern di workflow qui sotto per creare video karaoke, personalizzare lo stile ed esportare file MP4 in modo sicuro.

### Dai un prompt al tuo agente

Dopo aver installato CLI e skill, puoi assegnare al tuo agente un compito diretto come questo:

<CodeGroup>
  ```text local-file theme={null}
  Usa Youka per creare un video karaoke da /path/to/song.mp3. Trascrivi i testi in inglese, usa uno stile di sottotitoli karaoke pulito, esporta il video finale in 1080p e salvalo come ./karaoke.mp4.
  ```

  ```text url theme={null}
  Usa Youka per creare un video karaoke da https://example.com/song.mp4. Se mancano dipendenze per gli URL, installale prima. Poi trascrivi automaticamente i testi, usa uno stile di sottotitoli karaoke pulito, esporta il video finale e salvalo come ./karaoke.mp4.
  ```
</CodeGroup>

## Regole operative

<CardGroup cols={2}>
  <Card title="Usa sempre --json" icon="code">
    Nella CLI, passa sempre `--json`. Nell’API, imposta sempre `Accept:
            application/json`. Non interpretare mai output pensato per gli esseri umani.
  </Card>

  <Card title="Invia sempre una chiave di idempotenza" icon="rotate">
    Ogni scrittura dovrebbe includere una chiave di idempotenza stabile, così i tentativi dopo un timeout
    restituiscono il risultato originale invece di duplicare il lavoro.
  </Card>

  <Card title="Rileggi lo stato persistente" icon="database">
    Non fidarti di risposte di mutazione obsolete. Dopo un task terminale, rileggi il
    progetto o l’export per ottenere lo stato finale.
  </Card>

  <Card title="Esegui polling con backoff" icon="hourglass">
    Inizia con un intervallo di 2–3 secondi. Applica backoff esponenziale per job lunghi.
    Rispetta le risposte 429.
  </Card>
</CardGroup>

## Contratto di output

Ogni comando CLI in modalità `--json` scrive esattamente una busta su stdout.

Successo:

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

Errore:

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

Codici di uscita:

| Code | Meaning                                              | Retry?                       |
| ---- | ---------------------------------------------------- | ---------------------------- |
| `0`  | Successo.                                            | N/A                          |
| `1`  | Errore runtime (rete, API, rendering).               | Controlla `error.retryable`. |
| `2`  | Input non valido (flag errati, payload illeggibile). | No — correggi l’input.       |

## Workflow end-to-end

Il workflow canonico dell’agente è: creare un progetto, attendere, esportare, scaricare il risultato. Ecco il pattern completo con implementazioni sia CLI sia 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/it/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>

## Linee guida per il polling

La maggior parte delle operazioni di scrittura restituisce handle di operazioni nell’SDK. Preferisci `client.projects.wait(...)` e `client.exports.wait(...)` e scendi a `client.tasks.*` solo quando ti serve esplicitamente un accesso a basso livello ai task.

| Job type                                | Recommended initial interval | Max wait |
| --------------------------------------- | ---------------------------- | -------- |
| Creazione progetto (stems + sync testi) | 3 s                          | 15 min   |
| Solo separazione stems                  | 3 s                          | 10 min   |
| Solo sync testi                         | 2 s                          | 5 min    |
| Render export                           | 3 s                          | 30 min   |

Nella CLI, `--wait` gestisce il polling per te. Nell’SDK, gli helper di attesa usano un intervallo di 2 s per impostazione predefinita e accettano `pollIntervalMs`.

<Tip>
  Rispetta le risposte 429. In caso di rate limit, applica backoff di almeno il valore dell’header `Retry-After`
  (o 30 s se assente).
</Tip>

## Chiavi di idempotenza

Ogni operazione di creazione e aggiornamento supporta una chiave di idempotenza. Regole:

* Usa una chiave **stabile, unica, deterministica** per ogni mutazione logica. Bene: `create-song-${sourceHash}`. Male: un UUID nuovo a ogni tentativo.
* Riutilizza la **stessa** chiave tra i retry. Il server riconosce il replay e restituisce il risultato originale.
* Le chiavi sono con scope per account e scadono dopo 24 ore.
* Se il server restituisce `IDEMPOTENT_REPLAY_IN_PROGRESS` (HTTP 202), la richiesta originale è ancora in esecuzione. Attendi e riprova con la stessa chiave.

Pattern di esempio:

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

Vedi [API idempotency](/it/api/idempotency) per il contratto completo.

## Recupero dagli errori

Fai branching su `error.code` e `error.retryable`. I casi comuni:

| Code                                  | Cause                                                                | Action                                                |
| ------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------- |
| `INVALID_REQUEST`                     | Il body della richiesta non ha superato la validazione dello schema. | Correggi il payload. Nessun retry.                    |
| `UNAUTHORIZED`                        | API key mancante o non valida.                                       | Mostralo al chiamante. Nessun retry.                  |
| `NOT_FOUND`                           | La risorsa non esiste o non hai accesso.                             | Nessun retry.                                         |
| `CONFLICT` (409)                      | Conflitto di versione o collisione di idempotenza.                   | Riprova con la stessa chiave di idempotenza.          |
| `TOO_MANY_REQUESTS` (429)             | Rate limit.                                                          | Back off di `Retry-After` o 30 s.                     |
| `INTERNAL_SERVER_ERROR` (500)         | Errore transitorio del server.                                       | Riprova fino a 3 volte con backoff.                   |
| `IDEMPOTENT_REPLAY_IN_PROGRESS` (202) | La richiesta precedente è ancora in esecuzione.                      | Attendi e riprova con la stessa chiave.               |
| `TASK_FAILED`                         | Il task asincrono è terminato con errore.                            | Mostra `error.task.error` al chiamante. Nessun retry. |
| `TASK_TIMED_OUT`                      | Il task asincrono ha superato il tempo previsto.                     | Sicuro riprovare una volta.                           |

## Scoperta dei campi modificabili

Prima di modificare i preset, recupera lo schema del preset così il modello conosce i campi validi e i tipi di valore:

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

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

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

Per le impostazioni del progetto, è preferibile leggere prima le impostazioni correnti del progetto, poi inviare un body di aggiornamento minimo tramite `youka project settings <id> --body ...`.

Recupera una sola volta per sessione dell’agente e memorizza in cache il risultato.

## Agenti in parallelo

Quando più agenti vengono eseguiti in contemporanea sullo stesso account:

* Applica lo scope delle chiavi di idempotenza sia all’identità dell’agente sia alla mutazione logica: `agent-${agentId}-create-${sourceHash}`. Questo impedisce che il retry di un agente collida con una richiesta nuova di un altro agente.
* Mantieni le letture senza vincoli — le richieste `GET` sono economiche e non hanno effetti collaterali.
* Usa una singola coda per `POST /projects/{projectId}/exports` per progetto se ti serve una cronologia degli export ordinata. Altrimenti gli export possono arrivare fuori ordine.

## Cosa fare dopo

* [CLI global options](/it/cli/global-options) — tutti i flag disponibili per gli agenti
* [SDK errors](/it/sdk/errors) — riferimento completo alle classi di errore
* [API async jobs](/it/api/async-jobs) — il contratto di polling
* [API idempotency](/it/api/idempotency) — il contratto di idempotenza
