{"_id":"@adatechnology/audio-transcription-provider","_rev":"4-9101faaf41d1cd252d842766bfd32189","name":"@adatechnology/audio-transcription-provider","dist-tags":{"latest":"0.1.0","rc":"0.1.0-rc.2"},"versions":{"0.1.0-rc.1":{"name":"@adatechnology/audio-transcription-provider","version":"0.1.0-rc.1","keywords":["transcription","speech-to-text","whisper","groq","pt-br","whatsapp"],"author":{"name":"Ada Technology"},"license":"MIT","_id":"@adatechnology/audio-transcription-provider@0.1.0-rc.1","maintainers":[{"name":"miyazaki","email":"andersonfrfilho@gmail.com"}],"dist":{"shasum":"f6d6144d8b050392b1aaa551a4c2517a970ff5ba","tarball":"https://registry.npmjs.org/@adatechnology/audio-transcription-provider/-/audio-transcription-provider-0.1.0-rc.1.tgz","fileCount":9,"integrity":"sha512-v46OyWwj/H5gGdhYixiA43faXpihDpYtCVizVmTcejOGdSu6eMS3zmWI1zdyVvwi+BjHVHBz3jU5C31lcJGiKQ==","signatures":[{"sig":"MEQCIH/GEAkLi8dfHA2DLs0D0yRmT7ovcaOTER1Yyud15cF6AiAoiLF1RakKcuhxLeW7D3tbazzfP6me0yLyHOcDO6APow==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":36774},"main":"dist/index.js","type":"module","_from":"file:adatechnology-audio-transcription-provider-0.1.0-rc.1.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./whisper-local":{"types":"./dist/whisper-local/index.d.ts","import":"./dist/whisper-local/index.js","default":"./dist/whisper-local/index.js"}},"scripts":{"test":"bun test","build":"tsup","check":"tsc --noEmit","format":"prettier --write package.json src tsconfig.json tsup.config.ts","format:check":"prettier --check package.json src tsconfig.json tsup.config.ts"},"_npmUser":{"name":"miyazaki","email":"andersonfrfilho@gmail.com"},"_resolved":"/tmp/0ed3e863a33a3cf06087e4016793b26b/adatechnology-audio-transcription-provider-0.1.0-rc.1.tgz","_integrity":"sha512-v46OyWwj/H5gGdhYixiA43faXpihDpYtCVizVmTcejOGdSu6eMS3zmWI1zdyVvwi+BjHVHBz3jU5C31lcJGiKQ==","_npmVersion":"10.9.8","description":"Speech-to-text for conversational products: hosted Whisper (Groq) by default, local whisper.cpp opt-in, chainable","directories":{},"sideEffects":false,"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","@types/bun":"1.3.14","typescript":"^5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/audio-transcription-provider_0.1.0-rc.1_1785852816448_0.6267392278903601","host":"s3://npm-registry-packages-npm-production"}},"0.1.0-rc.2":{"name":"@adatechnology/audio-transcription-provider","version":"0.1.0-rc.2","keywords":["transcription","speech-to-text","whisper","groq","pt-br","whatsapp"],"author":{"name":"Ada Technology"},"license":"MIT","_id":"@adatechnology/audio-transcription-provider@0.1.0-rc.2","maintainers":[{"name":"miyazaki","email":"andersonfrfilho@gmail.com"}],"dist":{"shasum":"36bfb6d866c07c74cff40f6387db54f8b63147d7","tarball":"https://registry.npmjs.org/@adatechnology/audio-transcription-provider/-/audio-transcription-provider-0.1.0-rc.2.tgz","fileCount":9,"integrity":"sha512-J8wpasuLB7NSO1LFiqxLc8i5fkhJliaAavmJ417+RVyxqVQgKNqLt1GCgXbCYuvmZv0iDduH0X+DXVXrDdj8Lg==","signatures":[{"sig":"MEUCIQCcdIUMKB3EcJ/KEiSI8OzRSQarLLOZiYxUPM56Vyxh0QIgVoHAXk51LtdKJVKB6/K7J8WjBTWu/a/b8bUVpzb61cc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42622},"main":"dist/index.js","type":"module","_from":"file:adatechnology-audio-transcription-provider-0.1.0-rc.2.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./whisper-local":{"types":"./dist/whisper-local/index.d.ts","import":"./dist/whisper-local/index.js","default":"./dist/whisper-local/index.js"}},"scripts":{"test":"bun test","build":"tsup","check":"tsc --noEmit","format":"prettier --write package.json src tsconfig.json tsup.config.ts","format:check":"prettier --check package.json src tsconfig.json tsup.config.ts"},"_npmUser":{"name":"miyazaki","email":"andersonfrfilho@gmail.com"},"_resolved":"/tmp/b7198eda0c346380fc4d18bd624b54ce/adatechnology-audio-transcription-provider-0.1.0-rc.2.tgz","_integrity":"sha512-J8wpasuLB7NSO1LFiqxLc8i5fkhJliaAavmJ417+RVyxqVQgKNqLt1GCgXbCYuvmZv0iDduH0X+DXVXrDdj8Lg==","_npmVersion":"10.9.8","description":"Speech-to-text for conversational products: hosted Whisper (Groq) by default, local whisper.cpp opt-in, chainable","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","@types/bun":"1.3.14","typescript":"^5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/audio-transcription-provider_0.1.0-rc.2_1787861372827_0.8583301584843321","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@adatechnology/audio-transcription-provider","version":"0.1.0","description":"Speech-to-text for conversational products: hosted Whisper (Groq) by default, local whisper.cpp opt-in, chainable","type":"module","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./whisper-local":{"types":"./dist/whisper-local/index.d.ts","import":"./dist/whisper-local/index.js","default":"./dist/whisper-local/index.js"}},"sideEffects":false,"keywords":["transcription","speech-to-text","whisper","groq","pt-br","whatsapp"],"author":{"name":"Ada Technology"},"license":"MIT","publishConfig":{"access":"public"},"devDependencies":{"@types/bun":"1.3.14","tsup":"^8.5.1","typescript":"^5.9.3"},"scripts":{"build":"tsup","check":"tsc --noEmit","test":"bun test","format":"prettier --write package.json src tsconfig.json tsup.config.ts","format:check":"prettier --check package.json src tsconfig.json tsup.config.ts"},"_id":"@adatechnology/audio-transcription-provider@0.1.0","_integrity":"sha512-QheTBjW+mazCZlx3RUtfWc/y6HhaMiLE7u3mowkX9vR4fRjfNFMpwrKRE9pzyJTV92ersVx+8CizP3kvqia1sw==","_resolved":"/tmp/b67daf8a2341c76be85f204cd1c155af/adatechnology-audio-transcription-provider-0.1.0.tgz","_from":"file:adatechnology-audio-transcription-provider-0.1.0.tgz","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-QheTBjW+mazCZlx3RUtfWc/y6HhaMiLE7u3mowkX9vR4fRjfNFMpwrKRE9pzyJTV92ersVx+8CizP3kvqia1sw==","shasum":"65c7710c08b26c95c1772192d0a2e2c9775e7d18","tarball":"https://registry.npmjs.org/@adatechnology/audio-transcription-provider/-/audio-transcription-provider-0.1.0.tgz","fileCount":9,"unpackedSize":42617,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAJiDsGFnYZfoPkmcLonKXEyVE2YYHZJXRFlTKW06VUTAiB1ceLyY2p2UhLeBjeQ/vSeAAC0rjPGnZ+MfgMW9QtyrA=="}]},"_npmUser":{"name":"miyazaki","email":"andersonfrfilho@gmail.com"},"directories":{},"maintainers":[{"name":"miyazaki","email":"andersonfrfilho@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/audio-transcription-provider_0.1.0_1788318087962_0.943104427709716"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-04T14:13:36.281Z","modified":"2026-09-02T03:01:28.269Z","0.1.0-rc.1":"2026-08-04T14:13:36.596Z","0.1.0-rc.2":"2026-08-27T20:09:32.983Z","0.1.0":"2026-09-02T03:01:28.091Z"},"author":{"name":"Ada Technology"},"license":"MIT","keywords":["transcription","speech-to-text","whisper","groq","pt-br","whatsapp"],"description":"Speech-to-text for conversational products: hosted Whisper (Groq) by default, local whisper.cpp opt-in, chainable","maintainers":[{"name":"miyazaki","email":"andersonfrfilho@gmail.com"}],"readme":"# @adatechnology/audio-transcription-provider\n\nSpeech-to-text para produtos conversacionais. Engine hospedado (Groq/Whisper) por padrão, engine local (whisper.cpp) como opt-in, e uma cadeia para encadear os dois.\n\nPacote **standalone**: não depende de `@adatechnology/meta-whatsapp-*`. O que atravessa a fronteira é um buffer de áudio e um mime — qualquer canal serve.\n\n## Instalação\n\n```bash\npnpm add @adatechnology/audio-transcription-provider\n```\n\nO engine padrão não tem dependências: usa `fetch`, `FormData` e `Blob` globais (Node 18+, Bun).\n\n## Uso\n\n```ts\nimport { createGroqTranscriber } from '@adatechnology/audio-transcription-provider'\n\nconst transcriber = createGroqTranscriber({ apiKey: environment.GROQ_API_KEY })\n\nconst { text, language, durationSeconds } = await transcriber.transcribe({\n  buffer: audioBuffer,\n  mimeType: 'audio/ogg; codecs=opus',\n})\n```\n\nO pacote nunca lê `process.env` — a chave entra por parâmetro, como todo o resto do monorepo.\n\n## Cadeia de engines\n\nAdicionar um engine de reserva é configuração, não refactor:\n\n```ts\nimport { createGroqTranscriber, createTranscriberChain } from '@adatechnology/audio-transcription-provider'\nimport { createWhisperLocalTranscriber } from '@adatechnology/audio-transcription-provider/whisper-local'\n\nconst transcriber = createTranscriberChain(\n  [\n    createGroqTranscriber({ apiKey: environment.GROQ_API_KEY }),\n    createWhisperLocalTranscriber({ modelPath: '/models/ggml-large-v3-turbo.bin' }),\n  ],\n  { onEngineFailure: (error, { engine }) => logger.warn('transcrição degradou', { engine, error }) },\n)\n```\n\nA cadeia tenta o próximo engine **mesmo em erro definitivo**, porque suporte a codec varia: o Groq recusa AMR, e o engine local com ffmpeg na frente converte AMR sem reclamar.\n\n## Erros: retriável vs. definitivo\n\nA distinção que importa para quem consome é `isRetriable`.\n\n| Erro | `isRetriable` | O que fazer |\n|---|---|---|\n| `TranscriptionRateLimitError` | `true` | Reenfileirar respeitando `retryAfterSeconds` |\n| `TranscriptionError` (5xx, rede, timeout) | `true` | Reenfileirar com backoff |\n| `TranscriptionUnsupportedError` | `false` | Encerrar — nenhum retry conserta codec |\n| `TranscriptionError` (401, arquivo grande, áudio vazio) | `false` | Encerrar e alertar |\n\nEstourar cota é espera; codec desconhecido é definitivo. Sem essa distinção, quem consome só sabe \"não transcreveu\" e escolhe entre desistir de um áudio que funcionaria em dez minutos ou reprocessar para sempre um formato impossível.\n\n## Limites do engine hospedado (Groq)\n\n| | Free tier | Dev tier |\n|---|---|---|\n| Requisições/min | 20 | maior |\n| Requisições/dia | 2.000 | maior |\n| Segundos de áudio/hora | 7.200 | maior |\n| Segundos de áudio/dia | 28.800 | maior |\n| Tamanho máximo | 25MB | 100MB |\n\nNota de voz do WhatsApp não passa de 16MB, então o teto de tamanho não encosta. A cobrança tem **piso de 10 segundos por requisição** — cem áudios de 2s custam o mesmo que cem de 10s.\n\nFormatos aceitos: `flac`, `mp3`, `mp4`, `mpeg`, `mpga`, `m4a`, `ogg`, `wav`, `webm`. OGG/Opus — o que a Meta entrega — vai direto, sem conversão.\n\n## Engine local (opt-in)\n\nImportado de `@adatechnology/audio-transcription-provider/whisper-local`, subpath separado para que quem usa só o hospedado não carregue `node:child_process` nem a exigência de binários na imagem.\n\nExige na imagem: `ffmpeg` (o whisper.cpp só lê WAV PCM 16kHz mono) e o binário `whisper-cli` mais um modelo ggml. O trecho de Dockerfile Alpine está no cabeçalho de [`whisper-local.service.ts`](src/whisper-local/whisper-local.service.ts).\n\nUse `large-v3-turbo` (~1.6GB). Os modelos menores não erram só um pouco mais em pt-BR: trocam palavras e entram em loop de repetição em áudio de celular, e o que sai não é uma transcrição pior, é uma transcrição inútil. Como o turbo tem apenas 4 camadas de decoder, ele é muito mais rápido que o `large-v3` cheio. `small` (~488MB) segue aceitável onde a memória da imagem for o limite; `base` (~148MB) não vale a economia.\n\nMedido com `large-v3-turbo` em áudio real de reunião gravado por celular (7min38s, m4a): **61,9s** de ponta a ponta — conversão ffmpeg incluída — em Apple M3 Pro com Metal, sem nenhuma repetição consecutiva acima de 2 segmentos em 530. Esse número é de GPU de laptop; **em CPU de container Linux espere bem mais lento**, e é por isso que o timeout padrão é de 10 minutos. Meça no seu runner antes de dimensionar a fila.\n\nO engine local roda com `--max-context 0`: cada janela de 30s decodifica sem receber o texto da anterior como prompt, que é justamente o que realimenta o loop de repetição.\n\n## Testes\n\n```bash\nbun test\n```\n\n`fetchImplementation` é injetável — a suíte do engine hospedado roda inteira sem rede.\n","readmeFilename":"README.md"}