Você pode testar esta rota diretamente em nossa documentação interativa.

Recebe um texto bruto e devolve blocos temáticos rotulados pela IA — cada bloco é autocontido e pode ser processado separadamente sem perder contexto. Quando options.persistChunks é true, cada bloco é gravado em public.chunks com embedding no dataset escolhido, pronto para RAG.

Endpoint

POST /api/externalAPIs/public/smartSplit/partition

Parâmetros

text
string

Texto a ser particionado. Obrigatório se mediaUrls não for fornecido.

mediaUrls
string[]

URLs de mídia (imagens, PDFs, áudio, vídeo) convertidas em texto antes do particionamento. Obrigatório se text não for fornecido; ambos podem ser enviados juntos — o texto das mídias é concatenado antes do text.

hostId
string

ID do host. Inferido do token quando omitido; obrigatório para tokens de master admin.

avatarId
string

ID do avatar vinculado ao destino da persistência. Quando persistChunks: true e omitido, usa o avatar principal do host.

datasetId
string

ID do dataset que receberá os chunks. Quando persistChunks: true e omitido, o comportamento depende de options.createDatasetIfMissing.

options.persistChunks
boolean
default: "false"

Quando true, cada bloco é gravado como chunk pesquisável no dataset.

options.createDatasetIfMissing
boolean
default: "true"

Quando true e persistChunks: true sem datasetId, cria um dataset novo com nome gerado por IA. Quando false, usa o dataset mais antigo vinculado ao avatar; retorna erro se nenhum existir.

options.returnBlocks
boolean
default: "true"

Quando true, cada bloco retorna { text, label }. Quando false, retorna { ranges, label } com intervalos [start, end] inclusivos de linhas.

options.generalInstructions
string

Instruções livres anexadas ao prompt da IA (ex: "Agrupe por capítulo").

options.model
string
default: "gpt-4.1-nano"

Modelo LLM usado no particionamento.

options.provider
string
default: "openai"

Provedor do modelo LLM.

options.maxLinesPerSession
integer
default: "400"

Máximo de linhas por janela de sessão de IA.

options.overlapLines
integer
default: "30"

Linhas repetidas entre janelas adjacentes para continuidade de contexto.

options.minCoverage
number
default: "0.90"

Fração mínima de linhas que precisa ser coberta (0–1).

options.maxCharsPerChunk
integer
default: "80000"

Tamanho máximo em caracteres de cada sub-texto na pré-divisão de textos longos.

options.fallbackMaxCharsPerBlock
integer
default: "3000"

Tamanho máximo em caracteres de cada bloco gerado pelo fallback mecânico.

options.includeUncoveredLines
boolean
default: "true"

Quando true, a resposta inclui uncoveredLines com índices e texto das linhas fora de cobertura.

A API aceita tanto camelCase quanto snake_case nos parâmetros. text ou mediaUrls é obrigatório; ambos podem ser fornecidos simultaneamente.

Exemplos

O único campo obrigatório no body é text. Todos os outros são opcionais.

curl -X POST {{BASE_URL}}/api/externalAPIs/public/smartSplit/partition \
  -H "Authorization: Bearer {{TOKEN}}" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Chapter 1. The Beginning.\n\nOnce upon a time in a land far away, a young hero set out on a journey.\n\nChapter 2. The Challenge.\n\nThe road ahead was long. Mountains blocked the path.\n\nChapter 3. The Resolution.\n\nAfter many trials, the hero returned home, forever changed."
  }'

Resposta

{
  "success": true,
  "blocks": [
    { "text": "Capítulo 1. O início.\n\nEra uma vez em uma terra distante...", "label": "Capítulo 1 – O início" },
    { "text": "Capítulo 2. O desafio.\n\nO caminho era longo...", "label": "Capítulo 2 – O desafio" },
    { "text": "Capítulo 3. A resolução.\n\nApós muitas provações...", "label": "Capítulo 3 – A resolução" }
  ],
  "coverage": 1.0,
  "totalLines": 9,
  "sessionsUsed": 1,
  "fallbackUsed": false,
  "failedSessions": 0,
  "reasoning": "Agrupado pelos cabeçalhos de capítulo.",
  "auditLog": [
    "[SmartSplit] Iniciando particionamento de texto...",
    "[SmartSplit] Texto dividido em 9 linha(s)",
    "[SmartSplit] 1 sessão(ões) de IA necessária(s)",
    "[SmartSplit] 3 bloco(s) montado(s)",
    "[SmartSplit] Cobertura: 100.0% (9/9)",
    "[SmartSplit] Particionamento concluído com sucesso"
  ],
  "persisted": null,
  "uncoveredLines": { "count": 0, "indices": [], "ranges": [], "lines": [] },
  "costControl": {
    "usage": {
      "inputTokens": 480,
      "outputTokens": 95,
      "totalTokens": 575,
      "isEstimated": false,
      "source": "smart_split_aggregate"
    },
    "cost": {
      "inputCost": 0.000048,
      "outputCost": 0.000038,
      "totalCost": 0.000086,
      "currency": "USD",
      "pricingMissing": false,
      "matchedPricingKey": "openai:gpt-4.1-nano"
    },
    "control": { "decision": "allow", "reasons": [] },
    "references": { "caller": "smartSplit", "provider": "openai", "model": "gpt-4.1-nano" },
    "reconciliation": null
  }
}

Campos da Resposta

success
boolean

true quando a cobertura atinge o limiar e não houve erro fatal.

blocks
object[]

Blocos resultantes. O formato depende de options.returnBlocks.

coverage
number

Fração das linhas originais cobertas pelos blocos (0–1).

totalLines
integer

Número total de linhas do texto de entrada.

sessionsUsed
integer

Número de sessões de IA consumidas (uma por janela deslizante).

fallbackUsed
boolean

true quando ao menos uma janela precisou usar divisão mecânica em vez de IA.

failedSessions
integer

Número de janelas que retornaram 0 blocos e acionaram o fallback.

reasoning
string | null

Última reasoning do modelo, quando disponível.

auditLog
string[]

Rastro passo a passo do particionamento. Útil para depuração.

persisted
object | null

Presente quando options.persistChunks: true e a gravação ocorreu.

uncoveredLines
object

Linhas do input que não foram cobertas por nenhum bloco. Presente quando options.includeUncoveredLines: true (padrão).

costControl
object | null

Dados de consumo e custo da operação. null em erros internos.

Use options.returnBlocks: false quando precisar apenas dos intervalos de linha cobertos (útil para reprocessamento ou auditoria) em vez do texto completo do bloco.

Erros

CódigoDescrição
400text e mediaUrls ausentes ou vazios; hostId não resolvível
401Token inválido ou ausente
500Falha do LLM não recuperável após fallback; erro de inserção no banco durante a persistência

Quando a cobertura fica abaixo do limiar, a resposta volta com HTTP 200, success: false e reason: "coverage_below_threshold" junto com os blocos parciais.

Como funciona

flowchart TD
    client[Cliente] -->|POST /partition| ctrl[PartitionController]
    ctrl --> auth["Autenticação e resolução de hostId/avatarId/datasetId"]
    auth --> media["Resolução de mídias (se mediaUrls fornecido)"]
    media --> preChunk["Pré-chunking se texto > 80k chars"]
    preChunk --> lines["Divisão em linhas (sentence-parse + cap 50 palavras)"]
    lines --> windows["Janelas deslizantes (400 linhas, 30 overlap)"]
    windows --> ia["Sessão de IA por janela"]
    ia -->|0 blocos| fallback["Fallback mecânico (fallbackMaxCharsPerBlock chars/bloco)"]
    ia -->|blocos| assemble
    fallback --> assemble[Montar blocos e validar cobertura]
    assemble -->|persistChunks true| persist["Gerar nome, criar dataset se necessário, gravar chunks"]
    assemble -->|persistChunks false| shape[Shape da resposta]
    persist --> shape
    shape --> client
  1. Autenticação e resolução de contexto — o token é decodificado para extrair hostId e userId. Se persistChunks: true, o avatarId e o datasetId são resolvidos (ou derivados do avatar principal) e validados para garantir que pertencem ao host autenticado, bloqueando acesso cross-tenant.
  2. Resolução de mídias — quando mediaUrls é fornecido, cada URL (imagem, PDF, áudio, vídeo) é processada via mediaAnalysisV3 e convertida em texto. O resultado é concatenado ao text antes das etapas seguintes.
  3. Pré-chunking acima de 80 000 caracteres — textos maiores que options.maxCharsPerChunk (padrão 80 000) são quebrados em sub-textos independentes via cortes em fronteiras naturais (parágrafo → quebra de linha → sentença). Cada sub-texto é processado separadamente e os resultados são mesclados com offset global de linhas.
  4. Divisão em linhas — o texto é segmentado via sentence-parse (com observeMultipleLineBreaks: true). Linhas com mais de 50 palavras são subdivididas. Fallback para quebras de linha simples quando a biblioteca não retorna sentenças.
  5. Janelas deslizantes — acima de options.maxLinesPerSession linhas (padrão 400), o texto é cortado em janelas sobrepostas com options.overlapLines linhas de overlap (padrão 30) para manter contexto entre bordas.
  6. Sessão de IA por janela — cada janela vira uma chamada ao LLM com saída estruturada { blocks: [{ ranges, label }], reasoning }. O modelo retorna ranges inclusivos [start, end] (0-based); a expansão para índices individuais ocorre internamente.
  7. Fallback mecânico — se a IA devolver 0 blocos (recusa, parse inválido), a janela é dividida por caracteres até options.fallbackMaxCharsPerBlock (padrão 3 000) com label: null. A resposta sinaliza isso em fallbackUsed e failedSessions.
  8. Validação de cobertura — ao final, SmartSplit checa se pelo menos options.minCoverage (padrão 0.90) das linhas foi coberta. Se não, volta success: false com reason: "coverage_below_threshold", missingCount e os blocos parciais. Falhas de cobertura são registradas automaticamente no TypeSense para monitoramento.
  9. Persistência opcional — quando persistChunks: true, cada bloco é embeddado com text-embedding-3-large e inserido em public.chunks vinculado ao datasetId. Se o datasetId não foi passado e createDatasetIfMissing: true (padrão), as labels dos blocos alimentam um LLM que gera o nome do novo dataset antes da gravação. O objeto persisted na resposta traz datasetId, avatarId, datasetCreated, datasetName (quando criado), chunkIds e count.