Saltar al contenido principal

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.

El SDK @sf-voice/media envuelve la API de sf-voice media para aplicaciones TypeScript. Úsalo para enviar recursos multimedia, esperar a la indexación y buscar en superficies de vídeo, audio y transcripción con tus propios ID de recursos orientados al cliente.

Ingerir recursos

Envía contenido multimedia desde una URL, una clave de S3 o un buffer de archivo/navegador.

Conserva tus IDs

Pasa tu propio asset_id para que los resultados se vinculen a tu sistema.

Acotar la búsqueda

Usa asset_class o asset_ids para mantener la búsqueda vinculada al cliente o grupo correcto.
El SDK solo expone términos de sf-voice. El mapeo específico del proveedor ocurre en el backend.

¿Nuevo en sf-voice media?

Empieza con la visión general del producto antes de usar la referencia del SDK.

Instalación

pnpm add @sf-voice/media@latest

Crear un cliente

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,
});
OpciónObligatorioDescripción
baseUrlURL base de la API de sf-voice media.
apiKeyClave de API enviada como cabecera X-API-Key.
timeoutMsNoTiempo de espera por solicitud en milisegundos. Por defecto 30_000.

Campos principales

CampoDescripción
asset_idTu ID único para el recurso multimedia. Obligatorio al ingerir.
asset_classGrupo lógico opcional, como un cliente, workspace, proyecto o repositorio. Úsalo para acotar la búsqueda.
typesSuperficies multimedia opcionales a indexar o buscar: "video", "audio", "transcript".
metadataMetadatos planos opcionales de clave/valor. Los valores deben ser cadenas, números o booleanos.
thresholdPuntuación mínima de búsqueda opcional de 0.0 a 1.0. Valores más altos devuelven menos resultados, pero más fiables.

Cómo elegir asset_class

Usa asset_class para el límite dentro del cual tu producto debe buscar por defecto. Para la mayoría de productos orientados al cliente, ese es el cliente final, workspace, proyecto, repositorio o colección. Buenos ejemplos de asset_class:
  • customer_acme
  • workspace_123
  • project_onboarding
  • repo_mobile_app
No dependas de la búsqueda global para flujos orientados al cliente, a menos que cada usuario tenga permiso para buscar en todos los recursos indexados.

Flujo de extremo a extremo

1

Enviar un recurso

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

Esperar la indexación

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

Buscar en el contenido indexado

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 en navegador y servidor

El SDK funciona en cualquier entorno donde el runtime proporcione fetch, FormData y Blob.
RuntimeFuente de ingestión recomendada
App de navegadorsource: "file" para subidas directas desde inputs de archivo.
Servicio backendsource: "url" o source: "s3" cuando el contenido ya esté almacenado.
Runtime workersource: "url" o source: "file" según las API de cuerpo de solicitud disponibles.
Para archivos grandes, prefiere subir el contenido primero a tu capa de almacenamiento e ingerirlo por URL o clave de S3.

Ingestión

ingest(request) envía contenido multimedia para indexación y devuelve inmediatamente un ID de tarea.

Entrada

Campos comunes:
CampoObligatorioDescripción
asset_idTu ID único para el recurso.
asset_classNoGrupo lógico para el recurso. La búsqueda puede usarlo más adelante como ámbito.
media_typeNo"video" o "audio".
typesNoSuperficies a indexar: "video", "audio", "transcript".
metadataNoMetadatos planos de clave/valor para tu propia correlación.
Campos específicos de la fuente:
FuenteCampos obligatoriosDescripción
urlurlIngerir desde una URL pública o accesible desde el backend.
s3s3_keyIngerir desde una clave de S3 ya conectada a sf-voice.
filefile, filenameSubir un Blob, ArrayBuffer o Uint8Array directamente.

Ejemplos

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"],
});

Salida

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

Tareas y sondeo

Usa getTask(taskId) para obtener el estado de la tarea una vez. Usa pollTask(taskId, options) para esperar hasta que la tarea alcance "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;
};

Búsqueda

search(request) busca en el contenido indexado con lenguaje natural.
Prefiere asset_class o asset_ids para búsquedas orientadas al cliente. Usa scope: "all" solo cuando quieras buscar intencionadamente en todos los recursos.
La búsqueda tiene tres modos de acotación:
ModoEjemploÚsalo cuando
asset_class{ asset_class: "customer_acme" }Buscas en un cliente, workspace, proyecto o colección.
asset_ids{ asset_ids: ["video_123"] }Buscas en un conjunto conocido de recursos.
scope: "all"{ scope: "all" }Buscas intencionadamente en todos los recursos indexados.

Entrada

CampoObligatorioDescripción
queryConsulta de búsqueda en lenguaje natural.
typesNoQué superficies buscar: "video", "audio", "transcript".
asset_idsNoRestringe la búsqueda a IDs de recursos de cliente específicos.
asset_classNoRestringe la búsqueda a un grupo lógico. Recomendado para búsqueda acotada al cliente.
scopeNoEstablece en "all" solo cuando busques intencionadamente en todos los recursos.
thresholdNoPuntuación mínima de coincidencia de 0.0 a 1.0. Por defecto el valor predeterminado de la API.
pageNoNúmero de página.
limitNoMáximo de resultados por página.

Ejemplos

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

Salida

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 y end_ms son desplazamientos en milisegundos dentro del contenido de origen. Úsalos para saltar el reproductor directamente al momento coincidente.

Recursos

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

Errores

Cada respuesta de API no 2xx lanza 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 se lanza cuando una solicitud HTTP individual supera el tiempo de espera del cliente. SfVoiceMediaPollTimeoutError se lanza cuando pollTask supera su tiempo de espera de sondeo antes de que la tarea alcance "ready" o "failed".