{"_id":"@agency-lang/whisper-local","_rev":"4-c814cca360fe41493b61cfd138e753b0","name":"@agency-lang/whisper-local","dist-tags":{"latest":"0.0.4"},"versions":{"0.0.1":{"name":"@agency-lang/whisper-local","version":"0.0.1","author":{"name":"Aditya Bhargava"},"license":"ISC","_id":"@agency-lang/whisper-local@0.0.1","maintainers":[{"name":"egonschiele","email":"npm@adit.io"}],"homepage":"https://github.com/egonSchiele/agency-lang","bugs":{"url":"https://github.com/egonSchiele/agency-lang/issues"},"bin":{"agency-whisper":"dist/src/cli.js"},"dist":{"shasum":"dc98802ea3c9d63e0d0e497ee119f47c753a0bd9","tarball":"https://registry.npmjs.org/@agency-lang/whisper-local/-/whisper-local-0.0.1.tgz","fileCount":643,"integrity":"sha512-I63pGm0fEa3grWuVj7AGEmITpMqMR7CAKFoJ6mtQylCuXgTPNqu1YowgLHdF7F+wI0px8TALCZqNJDl/iN3Thg==","signatures":[{"sig":"MEYCIQCYTx7PAGkc2nSY6+b+pPXGNkDEIR2c/lbQM9+AdD7w5QIhAP6ckRoQbMhLtLmIHemHILk4+LYvf+Ui0/MxMRlaUQ/W","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":10607386},"main":"./dist/src/transcribe.js","type":"module","_from":"file:agency-lang-whisper-local-0.0.1.tgz","types":"./dist/src/transcribe.d.ts","agency":"./index.agency","exports":{".":{"types":"./dist/src/transcribe.d.ts","import":"./dist/src/transcribe.js"},"./package.json":"./package.json"},"gitHead":"a0b178258e7de28699bf9cc46f1178ea31f20640","scripts":{"test":"vitest","build":"pnpm run build:native && pnpm run build:ts","build:ts":"tsc","test:run":"vitest run","build:native":"cmake-js compile --runtime=node"},"_npmUser":{"name":"egonschiele","email":"npm@adit.io"},"_resolved":"/private/var/folders/mh/dp92mgm94_1c4b_yr1w17dsw0000gn/T/4e911dfc21c47f76da2a47c01fe252b6/agency-lang-whisper-local-0.0.1.tgz","_integrity":"sha512-I63pGm0fEa3grWuVj7AGEmITpMqMR7CAKFoJ6mtQylCuXgTPNqu1YowgLHdF7F+wI0px8TALCZqNJDl/iN3Thg==","_npmVersion":"10.9.2","description":"Local Whisper transcription for Agency using vendored whisper.cpp","directories":{},"_nodeVersion":"23.11.0","dependencies":{"cmake-js":"^7.3.0","node-addon-api":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.0.0","@types/node":"^25.0.6"},"peerDependencies":{"agency-lang":"0.1.2"},"_npmOperationalInternal":{"tmp":"tmp/whisper-local_0.0.1_1778680218525_0.11689189714204518","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@agency-lang/whisper-local","version":"0.0.2","author":{"name":"Aditya Bhargava"},"license":"ISC","_id":"@agency-lang/whisper-local@0.0.2","maintainers":[{"name":"egonschiele","email":"npm@adit.io"}],"homepage":"https://github.com/egonSchiele/agency-lang","bugs":{"url":"https://github.com/egonSchiele/agency-lang/issues"},"bin":{"agency-whisper":"dist/src/cli.js"},"dist":{"shasum":"448b190e45eb0227f56fe6d07f164184b3696547","tarball":"https://registry.npmjs.org/@agency-lang/whisper-local/-/whisper-local-0.0.2.tgz","fileCount":642,"integrity":"sha512-yudBMU0hSeY1vp+ELujsWPLP8HN1+L/+Joy+U6k0LcmhFDD2nTKxic9aoxnDZU3wXXjE3YCBxUcuJbnTOqslXA==","signatures":[{"sig":"MEUCIAP7znOYbA2VO8EeMcHPOkM8RMyLQM6usm8KKPNennUHAiEAtAQQHihjaw9r+Xtf37jVz/HkZOVPmgdZjH0romH32Lc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":8648792},"main":"./dist/src/transcribe.js","type":"module","_from":"file:agency-lang-whisper-local-0.0.2.tgz","types":"./dist/src/transcribe.d.ts","agency":"./index.agency","exports":{".":{"types":"./dist/src/transcribe.d.ts","import":"./dist/src/transcribe.js"},"./package.json":"./package.json"},"scripts":{"test":"vitest","build":"pnpm run build:native && pnpm run build:ts","build:ts":"tsc","test:run":"vitest run","build:native":"cmake-js compile --runtime=node"},"_npmUser":{"name":"egonschiele","email":"npm@adit.io"},"_resolved":"/private/var/folders/7v/4q_s04w13_dg2278232mcqz80000gn/T/6ad88a232df1789b80a23c5e3dea38c7/agency-lang-whisper-local-0.0.2.tgz","_integrity":"sha512-yudBMU0hSeY1vp+ELujsWPLP8HN1+L/+Joy+U6k0LcmhFDD2nTKxic9aoxnDZU3wXXjE3YCBxUcuJbnTOqslXA==","_npmVersion":"11.6.2","description":"Local Whisper transcription for Agency using vendored whisper.cpp","directories":{},"_nodeVersion":"25.1.0","dependencies":{"cmake-js":"^7.3.0","node-addon-api":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.0.0","@types/node":"^25.0.6","agency-lang":"0.9.0"},"peerDependencies":{"agency-lang":">=0.9.0"},"_npmOperationalInternal":{"tmp":"tmp/whisper-local_0.0.2_1784420668690_0.8719950215081476","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@agency-lang/whisper-local","version":"0.0.3","author":"Aditya Bhargava","license":"ISC","_id":"@agency-lang/whisper-local@0.0.3","maintainers":[{"name":"egonschiele","email":"npm@adit.io"}],"homepage":"https://github.com/egonSchiele/agency-lang","bugs":{"url":"https://github.com/egonSchiele/agency-lang/issues"},"bin":{"agency-whisper":"./dist/src/cli.js"},"dist":{"shasum":"34651c634bfd9fdc77414443871da21c258bf9d9","tarball":"https://registry.npmjs.org/@agency-lang/whisper-local/-/whisper-local-0.0.3.tgz","fileCount":646,"integrity":"sha512-Q03G5Nur/ETe5xtrVaPdf9isZRJ1EiIlWPwo8jnT1N1itxezzm+1KpTd9e9yqXbmaEvtH7HgUYeHMh3k0Rmk0A==","signatures":[{"sig":"MEYCIQDzHk6bgNughMJkSHmaqcUZlyTRgEk/jK4BYb0jH+q4PgIhAIKurKPnB0QTmGrX6fAVXP3iP/ZR4naScyK9B1+H4EVK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":10622965},"main":"./dist/src/transcribe.js","type":"module","agency":"./index.agency","exports":{".":{"types":"./dist/src/transcribe.d.ts","import":"./dist/src/transcribe.js"},"./package.json":"./package.json"},"scripts":{"test":"vitest","build":"pnpm run build:native && pnpm run build:ts","build:ts":"tsc","test:run":"vitest run","build:native":"cmake-js compile --runtime=node"},"_npmUser":{"name":"egonschiele","email":"npm@adit.io"},"description":"Local Whisper transcription for Agency using vendored whisper.cpp","directories":{},"_nodeVersion":"25.1.0","dependencies":{"cmake-js":"^7.3.0","node-addon-api":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.0.0","@types/node":"^25.0.6","agency-lang":"0.18.0"},"peerDependencies":{"agency-lang":">=0.9.0"},"_npmOperationalInternal":{"tmp":"tmp/whisper-local_0.0.3_1788649177277_0.7788621808962124","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"_id":"@agency-lang/whisper-local@0.0.4","bin":{"agency-whisper":"./dist/src/cli.js"},"bugs":{"url":"https://github.com/egonSchiele/agency-lang/issues"},"dist":{"shasum":"7e8ce3dfba0d612e5302b15b2d95479b8697ab46","tarball":"https://registry.npmjs.org/@agency-lang/whisper-local/-/whisper-local-0.0.4.tgz","fileCount":647,"integrity":"sha512-BV7BcyVNwnQLmVPMvvifUX2BzPH0sy1Y6OpaMbvpeYKzWky89K2ySDcXQiuPc91c+cmOW1gAHHMRr/SWJY3KxA==","signatures":[{"sig":"MEQCIAr9gyEZk6J/9cWRBdnOPcbCW7xM79bvqqDrRCZG4ETAAiAcEw5o633JcyHwEK1oVwsp9jQW4gsUqI+n9wi6OJuZPQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDC96voZzzqlkr+HSRBpwjTrQHNryvYj/xHm1fG8dEn3AIgL5cJFm+eZWlhSna/3xsQ5/TykMrlTcjhfrlG7Y6FEgo="}],"unpackedSize":10637220},"main":"./dist/src/transcribe.js","name":"@agency-lang/whisper-local","type":"module","agency":"./index.agency","author":"Aditya Bhargava","exports":{".":{"types":"./dist/src/transcribe.d.ts","import":"./dist/src/transcribe.js"},"./index.js":"./index.js","./package.json":"./package.json"},"license":"ISC","scripts":{"test":"vitest","build":"pnpm run build:native && pnpm run build:ts","build:ts":"tsc && node ../agency-lang/dist/scripts/agency.js compile index.agency","test:run":"vitest run","build:native":"cmake-js compile --runtime=node"},"version":"0.0.4","_npmUser":{"name":"egonschiele","email":"npm@adit.io"},"homepage":"https://github.com/egonSchiele/agency-lang","description":"Local Whisper transcription for Agency using vendored whisper.cpp","directories":{},"maintainers":[{"name":"egonschiele","email":"npm@adit.io"}],"_nodeVersion":"25.1.0","dependencies":{"cmake-js":"^7.3.0","node-addon-api":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.0.0","@types/node":"^25.0.6","agency-lang":"0.22.0"},"peerDependencies":{"agency-lang":">=0.19.3"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/whisper-local_0.0.4_1790265691545_0.27991778871574735"}}},"time":{"created":"2026-05-13T13:50:18.405Z","modified":"2026-09-24T16:01:31.798Z","0.0.1":"2026-05-13T13:50:18.883Z","0.0.2":"2026-07-19T00:24:28.881Z","0.0.3":"2026-09-05T22:59:37.482Z","0.0.4":"2026-09-24T16:01:31.650Z"},"bugs":{"url":"https://github.com/egonSchiele/agency-lang/issues"},"author":"Aditya Bhargava","license":"ISC","homepage":"https://github.com/egonSchiele/agency-lang","description":"Local Whisper transcription for Agency using vendored whisper.cpp","maintainers":[{"name":"egonschiele","email":"npm@adit.io"}],"readme":"# @agency-lang/whisper-local\n\nLocal Whisper transcription for Agency. No network at runtime, no API key, no data leaves your machine.\n\n## Installation\n\nThis package ships as source and ships **no** install/postinstall scripts — `npm install` will not run a compiler or fetch anything. After installing, run the explicit build step below to compile the native addon. This is intentional: postinstall scripts are the most common npm supply-chain attack vector, and silently invoking `cmake` on every install would surprise users who pulled the package as a transitive dependency.\n\n```sh\n# 1. Install (no compilation, no network beyond the npm download itself)\nnpm install @agency-lang/whisper-local\n\n# 2. Explicitly build the native addon (once per machine, ~30-90 seconds)\nnpx -p @agency-lang/whisper-local agency-whisper build\n```\n\nThe build is kept in `~/.agency/addons/whisper/` (override with\n`AGENCY_WHISPER_ADDON_DIR`), beside the models, so reinstalling the package\nor letting your package manager move it does not cost a rebuild. The file\nname carries the package version, platform, architecture, and Node ABI:\nafter upgrading this package or Node, run `agency-whisper build` again and\nthe old file is simply ignored.\n\n**System dependencies (install before running `agency-whisper build`):**\n\n| Platform | Build tools | Audio decoding |\n|----------|-------------|----------------|\n| macOS    | `xcode-select --install && brew install cmake` | `brew install ffmpeg` |\n| Debian/Ubuntu | `sudo apt install cmake build-essential` | `sudo apt install ffmpeg` |\n| Fedora   | `sudo dnf install cmake gcc-c++` | `sudo dnf install ffmpeg` |\n| Windows  | Not yet supported in source-build v0; wait for prebuilts. | — |\n\nIf `agency-whisper build` fails because of missing build tools, the rest of your `node_modules/` is unaffected.\n\n## Quick start\n\n```ts\nimport { transcribe } from \"pkg::@agency-lang/whisper-local\"\n\nnode main() {\n  const text = transcribe(\"interview.m4a\", \"en\", \"base.en\")\n  print(text)\n}\n```\n\nThe first call downloads `ggml-base.en.bin` (~150 MB) into `~/.agency/models/whisper/`. Subsequent calls reuse the cached file.\n\n## API\n\n```\ntranscribe(filepath: string, language: string = \"\", model: string = \"base.en\"): string\n```\n\n- `filepath` — any audio file ffmpeg can read (mp3, m4a, wav, flac, ogg, webm, mp4, …). Must be a regular file on the local filesystem; URLs and ffmpeg pseudo-protocols (`http://`, `concat:`, `subfile:`, …) are explicitly rejected. See [Operational notes](#operational-notes).\n- `language` — ISO 639-1 code (e.g. `\"en\"`, `\"fr\"`, `\"de\"`). Empty string → whisper.cpp auto-detects.\n- `model` — model name. See the table below.\n\nReturns the joined transcript text. Throws on missing ffmpeg, unknown model, corrupted audio, or SHA-256 mismatch on model download.\n\n## Models\n\nAll ten upstream whisper.cpp models are pinned in `models.lock.json` against HuggingFace commit [`5359861c…`](https://huggingface.co/ggerganov/whisper.cpp/tree/5359861c739e955e79d9a303bcbc70fb988958b1) with verified SHA-256 hashes.\n\n| Name | Size | English-only | Notes |\n|------|------|--------------|-------|\n| `tiny`           | 75 MB  | no  | Fastest, lowest accuracy. Good for quick prototypes. |\n| `tiny.en`        | 75 MB  | yes | English-only variant of `tiny`; slightly more accurate. |\n| `base`           | 142 MB | no  | Multilingual base model. |\n| `base.en`        | 142 MB | yes | **Default.** Good accuracy/speed trade-off for English. |\n| `small`          | 466 MB | no  | Noticeable accuracy bump over `base`. |\n| `small.en`       | 466 MB | yes | English-only variant of `small`. |\n| `medium`         | 1.5 GB | no  | Slow on CPU; usable on Apple Silicon. |\n| `medium.en`      | 1.5 GB | yes | English-only variant of `medium`. |\n| `large-v3`       | 2.9 GB | no  | Best accuracy. Use only with adequate RAM (~5 GB peak). |\n| `large-v3-turbo` | 1.6 GB | no  | Approaches `large-v3` quality at ~half the size. |\n\n`.en` variants are slightly more accurate on English-only audio. To add a model from a newer upstream release, see [`docs/DEV.md`](./docs/DEV.md#adding-a-model).\n\n## Pre-downloading models\n\n```sh\nnpx -p @agency-lang/whisper-local agency-whisper pull base.en\nnpx -p @agency-lang/whisper-local agency-whisper list\nnpx -p @agency-lang/whisper-local agency-whisper verify base.en\n```\n\n## Manual model placement\n\nIf you can't reach HuggingFace (network-restricted environment, etc.), download `ggml-<name>.bin` yourself and place it at `~/.agency/models/whisper/ggml-<name>.bin`. The package will use it as-is, without re-hashing on every load. To verify a manually-placed file:\n\n```sh\nnpx -p @agency-lang/whisper-local agency-whisper verify <name>\n```\n\n## Custom model directory\n\nSet `AGENCY_WHISPER_MODELS_DIR` to use a directory other than `~/.agency/models/whisper/`.\n\n## Operational notes\n\n**Threading.** The native addon runs whisper inference on a libuv worker thread (`Napi::AsyncWorker`), so the JavaScript event loop is *not* blocked during a `transcribe()` call. Other JS work — HTTP requests, timers, etc. — continues to run.\n\n**Per-model serialization.** A `whisper_context` is mutable internal state. We hold a per-model mutex around `whisper_full`, so concurrent `transcribe()` calls on the *same* model serialize cleanly (no races, no corruption) but do not run in parallel. Throughput per model is single-threaded.\n\n**Cross-model parallelism.** Calls on *different* model instances run concurrently on separate libuv worker threads. By default Node sizes the libuv pool at 4 threads. If you run many concurrent transcriptions in the same process (e.g. an Agency program serving multiple users), bump the pool: `UV_THREADPOOL_SIZE=16 node ...` Do this *before* node starts; the pool size is locked at startup.\n\n**Loaded-model cache.** Loaded model contexts are kept in an in-process LRU cache. The default cap is 2 entries (a `large-v3` context can use ~3 GB, so an unbounded cache is dangerous in long-lived processes). Override via `AGENCY_WHISPER_HANDLE_CACHE_MAX`. Set to `0` to disable the cache (load + free per `transcribe()`).\n\n**Memory profile.** The audio decode step buffers the entire decoded PCM in memory before handing it to whisper. At 16 kHz mono float32 that is ~230 MB per hour of audio. Peak RSS during a transcribe is roughly 3× the decoded size (decoded buffer + Float32Array copy + C++ `std::vector` copy). The package rejects any single decode that exceeds 2 GB by default; override per-call via the lower-level `decodeToPcm({ maxPcmBytes })` API or chunk long audio client-side.\n\n**Timeout.** Each ffmpeg invocation has a 10-minute wall-clock cap (configurable via `decodeToPcm({ timeoutMs })`). On expiry the ffmpeg process is `SIGKILL`-ed and the call rejects, so a stuck or pathological input cannot hold the worker forever.\n\n**Input restriction.** `transcribe(filepath)` validates that `filepath` is a regular file before spawning ffmpeg, and the spawn is restricted to ffmpeg's `file` protocol. Inputs starting with `-` or specifying any other protocol (`http://`, `tcp://`, `concat:`, `subfile:`, …) are rejected up front. This matters because Agency programs often pass LLM-driven tool arguments straight into `transcribe()`; without this guard, a crafted \"filepath\" could turn a transcription into an outbound HTTP fetch or a read of an arbitrary local file.\n\n## Troubleshooting\n\n**`cmake: command not found`** — install cmake (see the install table).\n\n**`ffmpeg not found on PATH`** — install ffmpeg (see the install table).\n\n**`whisper_init_from_file_with_params failed`** — the `.bin` file is corrupted or not a whisper.cpp ggml format. Re-download with `agency-whisper pull <name>` or run `agency-whisper verify <name>` to check.\n\n**`SHA-256 mismatch`** — the downloaded model's hash doesn't match the lockfile. The partial file has been deleted. Re-running usually succeeds; if it persists, file an issue.\n\n**`whisper-local native addon not found`** — you skipped step 2 of installation, or upgraded this package or Node since building. Run `npx -p @agency-lang/whisper-local agency-whisper build`.\n\n## Not in v0\n\n- Prebuilt binaries (will arrive via an optional-deps platform matrix).\n- Windows source-build support.\n- Streaming partial results.\n- Speaker diarization.\n- Translation mode.\n\n## For maintainers / contributors\n\nSee [`docs/DEV.md`](./docs/DEV.md) for architecture, security model, C++ memory design, vendoring procedure, and testing notes.\n\n## Credits\n\nThis package vendors and depends on:\n\n- **[whisper.cpp](https://github.com/ggml-org/whisper.cpp)** by Georgi Gerganov and contributors — MIT License. See `vendor/whisper.cpp/LICENSE`. We use a pinned release; see `vendor/whisper.cpp/VERSION`.\n- **[ggml](https://github.com/ggml-org/ggml)** by Georgi Gerganov and contributors — MIT License. Vendored alongside whisper.cpp.\n- **[node-addon-api](https://github.com/nodejs/node-addon-api)** by the Node.js project — MIT License.\n- **[cmake-js](https://github.com/cmake-js/cmake-js)** — MIT License.\n\nAudio decoding shells out to your system's **[ffmpeg](https://ffmpeg.org)**, which is not bundled or distributed with this package.\n\n## License\n\nISC. See repository root LICENSE file. Vendored whisper.cpp + ggml source is MIT-licensed; see `vendor/whisper.cpp/LICENSE` for that notice.\n","readmeFilename":""}