Vai al contenuto principale

Documentation Index

Fetch the complete documentation index at: https://docs.sf-voice.sh/llms.txt

Use this file to discover all available pages before exploring further.

L’SDK @sf-voice/media incapsula l’API sf-voice media per le applicazioni TypeScript. Usalo per inviare asset multimediali, attendere l’indicizzazione e cercare tra le superfici video, audio e trascrizione con i tuoi ID di asset rivolti ai clienti.

Ingerire gli asset

Invia contenuti da un URL, una chiave S3 o un buffer browser/file.

Mantieni i tuoi ID

Passa il tuo asset_id affinché i risultati si colleghino al tuo sistema.

Definisci l'ambito della ricerca

Usa asset_class o asset_ids per mantenere la ricerca legata al cliente o gruppo corretto.
L’SDK espone solo la terminologia di sf-voice. La mappatura specifica del provider avviene nel backend.

Nuovo su sf-voice media?

Inizia con la panoramica del prodotto prima di usare il riferimento dell’SDK.

Installazione

pnpm add @sf-voice/media@latest

Crea un client

import { SfVoiceMedia } from "@sf-voice/media";

const client = new SfVoiceMedia({
  baseUrl: "https://api.sf-voice.com",
  apiKey: process.env.SF_VOICE_API_KEY!,
  timeoutMs: 30_000,
});
OpzioneObbligatorioDescrizione
baseUrlURL base dell’API sf-voice media.
apiKeyChiave API inviata come header X-API-Key.
timeoutMsNoTimeout per richiesta in millisecondi. Predefinito 30_000.

Campi principali

CampoDescrizione
asset_idIl tuo ID univoco per l’asset multimediale. Obbligatorio in fase di ingestione.
asset_classRaggruppamento logico opzionale, come un cliente, workspace, progetto o repository. Usato per delimitare la ricerca.
typesSuperfici multimediali opzionali da indicizzare o cercare: "video", "audio", "transcript".
metadataMetadati piatti chiave/valore opzionali. I valori devono essere stringhe, numeri o booleani.
thresholdPunteggio minimo di ricerca opzionale da 0.0 a 1.0. Valori più alti restituiscono meno risultati, ma più affidabili.

Scegliere asset_class

Usa asset_class per il confine all’interno del quale il tuo prodotto dovrebbe cercare di default. Per la maggior parte dei prodotti rivolti al cliente, è il cliente finale, workspace, progetto, repository o raccolta. Buoni esempi di asset_class:
  • customer_acme
  • workspace_123
  • project_onboarding
  • repo_mobile_app
Non affidarti alla ricerca globale per i workflow rivolti al cliente, a meno che ogni utente sia autorizzato a cercare in ogni asset indicizzato.

Flusso end-to-end

1

Inviare un asset

const ingest = await client.ingest({
  source: "url",
  asset_id: "video_123",
  asset_class: "customer_acme",
  url: "https://example.com/recording.mp4",
  media_type: "video",
  types: ["video", "audio", "transcript"],
  metadata: {
    title: "product demo",
    customer_id: "acme",
  },
});
2

Attendere l'indicizzazione

const task = await client.pollTask(ingest.task_id, {
  intervalMs: 2_000,
  timeoutMs: 120_000,
});

if (task.status === "failed") {
  throw new Error(task.error ?? "ingest task failed");
}
3

Cercare nei contenuti indicizzati

const search = await client.search({
  query: "where does the customer mention pricing?",
  asset_class: "customer_acme",
  types: ["transcript"],
  threshold: 0.7,
  limit: 10,
});

console.log(search.results);

Uso lato browser e server

L’SDK funziona ovunque il runtime fornisca fetch, FormData e Blob.
RuntimeSorgente di ingestione consigliata
App browsersource: "file" per upload diretti da input file.
Servizio backendsource: "url" o source: "s3" quando il contenuto è già archiviato.
Runtime workersource: "url" o source: "file" a seconda delle API di corpo richiesta disponibili.
Per file di grandi dimensioni, preferisci caricare prima il contenuto sul tuo livello di archiviazione e ingerirlo tramite URL o chiave S3.

Ingestione

ingest(request) invia un contenuto multimediale per l’indicizzazione e restituisce immediatamente un ID di task.

Input

Campi comuni:
CampoObbligatorioDescrizione
asset_idIl tuo ID univoco per l’asset.
asset_classNoRaggruppamento logico per l’asset. La ricerca può usarlo successivamente come ambito.
media_typeNo"video" o "audio".
typesNoSuperfici da indicizzare: "video", "audio", "transcript".
metadataNoMetadati piatti chiave/valore per la tua correlazione.
Campi specifici della sorgente:
SorgenteCampi obbligatoriDescrizione
urlurlIngerire da un URL pubblico o accessibile dal backend.
s3s3_keyIngerire da una chiave S3 già collegata a sf-voice.
filefile, filenameCaricare direttamente un Blob, ArrayBuffer o Uint8Array.

Esempi

const ingest = await client.ingest({
  source: "url",
  asset_id: "video_123",
  asset_class: "customer_acme",
  url: "https://example.com/recording.mp4",
  media_type: "video",
  types: ["video", "audio", "transcript"],
});

Output

type IngestResponse = {
  asset_id: string;
  task_id: string;
  status: "pending";
};
{
  "asset_id": "video_123",
  "task_id": "task_abc123",
  "status": "pending"
}

Task e polling

Usa getTask(taskId) per recuperare lo stato di un task una volta. Usa pollTask(taskId, options) per attendere che il task raggiunga "ready" o "failed".
const task = await client.pollTask("task_abc123", {
  intervalMs: 2_000,
  timeoutMs: 120_000,
});
type Task = {
  task_id: string;
  asset_id: string;
  asset_class?: string;
  types: Array<"video" | "audio" | "transcript">;
  status: "pending" | "indexing" | "ready" | "failed";
  error?: string;
  created_at: string;
  completed_at?: string;
};

Ricerca

search(request) cerca nei contenuti indicizzati con linguaggio naturale.
Preferisci asset_class o asset_ids per la ricerca rivolta ai clienti. Usa scope: "all" solo quando vuoi intenzionalmente cercare in ogni asset.
La ricerca ha tre modalità di ambito:
ModalitàEsempioUsalo quando
asset_class{ asset_class: "customer_acme" }Cerchi in un cliente, workspace, progetto o raccolta.
asset_ids{ asset_ids: ["video_123"] }Cerchi in un insieme noto di asset.
scope: "all"{ scope: "all" }Cerchi intenzionalmente in ogni asset indicizzato.

Input

CampoObbligatorioDescrizione
queryQuery di ricerca in linguaggio naturale.
typesNoQuali superfici cercare: "video", "audio", "transcript".
asset_idsNoLimita la ricerca a ID di asset cliente specifici.
asset_classNoLimita la ricerca a un singolo raggruppamento logico. Consigliato per la ricerca limitata al cliente.
scopeNoImposta su "all" solo quando cerchi intenzionalmente in ogni asset.
thresholdNoPunteggio minimo di corrispondenza da 0.0 a 1.0. Predefinito quello dell’API.
pageNoNumero di pagina.
limitNoMassimo risultati per pagina.

Esempi

const search = await client.search({
  query: "refund policy",
  asset_class: "customer_acme",
  types: ["transcript"],
});

Output

type SearchResponse = {
  results: Array<{
    asset_id: string;
    score: number;
    start_ms: number;
    end_ms: number;
    match_type: "video" | "audio" | "transcript";
    thumbnail_url?: string;
  }>;
  page_info: {
    total: number;
    page: number;
    limit: number;
    next_page_token?: string;
  };
};
{
  "results": [
    {
      "asset_id": "video_123",
      "score": 0.84,
      "start_ms": 42000,
      "end_ms": 58000,
      "match_type": "transcript",
      "thumbnail_url": "https://api.sf-voice.com/assets/video_123/thumb.jpg"
    }
  ],
  "page_info": {
    "total": 1,
    "page": 1,
    "limit": 10
  }
}
start_ms ed end_ms sono offset in millisecondi nel contenuto sorgente. Usali per posizionare il player direttamente sul momento corrispondente.

Asset

const assets = await client.listAssets({ page: 1, limit: 20 });
const asset = await client.getAsset("video_123");
await client.deleteAsset("video_123");
type Asset = {
  asset_id: string;
  asset_class?: string;
  media_type: "video" | "audio";
  source_type: "url" | "s3" | "file";
  types: Array<"video" | "audio" | "transcript">;
  status: "pending" | "indexing" | "ready" | "failed";
  metadata?: Record<string, string | number | boolean>;
  duration_ms?: number;
  created_at: string;
  updated_at: string;
};

Errori

Ogni risposta API non 2xx genera SfVoiceMediaError.
import { SfVoiceMediaError } from "@sf-voice/media";

try {
  await client.search({
    query: "pricing",
    asset_class: "customer_acme",
  });
} catch (error) {
  if (error instanceof SfVoiceMediaError) {
    console.error(error.code);
    console.error(error.status);
    console.error(error.message);
  }
  throw error;
}
SfVoiceMediaRequestTimeoutError viene generato quando una singola richiesta HTTP supera il timeout del client. SfVoiceMediaPollTimeoutError viene generato quando pollTask supera il proprio timeout di polling prima che il task raggiunga "ready" o "failed".