@juspay/neurolink 12.58.1 → 12.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,8 +1,8 @@
1
- ## [12.58.1](https://github.com/juspay/neurolink/compare/v12.58.0...v12.58.1) (2026-10-15)
1
+ ## [12.59.0](https://github.com/juspay/neurolink/compare/v12.58.1...v12.59.0) (2026-10-15)
2
2
 
3
- ### Bug Fixes
3
+ ### Features
4
4
 
5
- - **(package):** ship no .tsx and keep fluent-ffmpeg types out of public declarations ([4591b12](https://github.com/juspay/neurolink/commit/4591b12247922e01756aa2fb933b19a1f4999807)), closes [#1999](https://github.com/juspay/neurolink/issues/1999)
5
+ - **(voice):** export the energy endpointer as @juspay/neurolink/voice/endpointer ([7bf7d39](https://github.com/juspay/neurolink/commit/7bf7d398cb39678d9a92e16a9b7f0dccf9177672))
6
6
 
7
7
  ## [11.2.3](https://github.com/juspay/neurolink/compare/v11.2.2...v11.2.3) (2026-08-19)
8
8
 
@@ -4542,6 +4542,7 @@
4542
4542
  {"objectID":"7c55169273332aab63f54e94bae343516bd630e062d60a4d427d004b72ee287e","title":"Nothing is ever dropped","url":"/docs/features/transcribe#nothing-is-ever-dropped","content":"Every layer fails open, and none may lose words:\nA rewrite that drops more than maxDropRatio of the words is discarded and\n the dictionary-applied text is kept.\nA rewrite that times out, fails or returns nothing keeps the text it was\n given.\nA guard that times out or fails applies the dictionary as is.\nWhen streaming, a final pass that returns less than the live text keeps the\n live text, and an utterance no engine could read is reported as a silence\n event with its length rather than disappearing.\nraw always holds the engine's own text, so a caller can show or diff it.\n\nEach of those outcomes is written to steps, so a degraded path is visible\nrather than silent.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Nothing is ever dropped","lvl3":""}},
4543
4543
  {"objectID":"c0207627f5f88b7914c2fbe84a641879ece05ae20f7e2194a9f0bc29c24cfd65","title":"Fallback and second opinion","url":"/docs/features/transcribe#fallback-and-second-opinion","content":"Fallback takes the request (or, when streaming, the utterance) when the\n primary engine cannot read it: when defaults to [\"unsure\", \"empty\"] — a\n low language-detection score, or no text — and \"error\" adds engine\n failures. engine.fallbackUsed says when it ran.\nSecond opinion runs a second engine on the same audio in parallel; the\n rewrite reconciles the two transcripts, taking each language's words from the\n engine that reads it better. When the primary reports an unsure language,\n or no text, the second opinion's text leads. With rewrite: false that is\n all it does — there is no reconciliation without the rewrite.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Fallback and second opinion","lvl3":""}},
4544
4544
  {"objectID":"c903ddf3ec717cab3ff063e2bbb762f634ff09b05e5199c35d95283aba82f2f6","title":"Streaming","url":"/docs/features/transcribe#streaming","content":"Engines with a native stream use it; every other engine is streamed on the\nclient by a chunked adapter (an energy gate finds utterances, the current\nutterance is re-transcribed every intervalMs, and the prefix two passes agree\non is committed). streaming.mode: \"chunked\" forces the adapter.\n\n| Event | Carries |\n| ------------ | ---------------------------------------------------------------------------------------------- |\n| interim | The utterance's current text, split into committed (stable) and tail (may still change). |\n| language | The detected language and whether the engine was sure. |\n| final | The utterance's final text, segment and words, the engine, and whether the fallback took it. |\n| correcting | Partial text of the streamed rewrite. |\n| corrected | The corrected text, its raw, decisions, steps and timings. |\n| silence | An utterance no engine could read, with its length. |\n| error | A message, and recoverable: true when the stream carries on with the next utterance. |\n\nTuning (streaming): sampleRate (16000), endSilenceMs (750), intervalMs\n(900), softCutSeconds (16), maxUtteranceSeconds (28), onsetRms (0.006),\nprerollMs (350), minSpeechMs (250).","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Streaming","lvl3":""}},
4545
+ {"objectID":"336d246e949117f5c2b68c49a693582dd2395b7515979d6566e5d07a7a65fd75","title":"Finding the end of a spoken turn in a browser","url":"/docs/features/transcribe#finding-the-end-of-a-spoken-turn-in-a-browser","content":"@juspay/neurolink/voice/endpointer exports the energy gate the chunked adapter\nuses. It is a self-contained module (no Node built-ins, no other imports), so a\nbrowser app can ask where a spoken turn starts and ends without running a speech\nengine and without bundling the voice entry.\nstart is tentative: a click also starts an utterance, and a drop follows\n about endSilenceMs later. end carries a reason: silence, softCut,\n hardCut or flush.\nFeed it a continuous stream of samples. The noise floor and every timer count\n samples, so polling an AnalyserNode on a timer gives wrong timings.\nThe noise floor starts at a fixed value and rises by at most about 2x per\n second. In a loud room the first two seconds can produce an utterance made of\n noise, so keep the gate running for about two seconds before trusting events.\nA signal that never dips (a fan, a steady hum) is absorbed as noise after a\n few seconds. It measures energy, not speech: background talk keeps a turn open\n until a cut.\nsoftCutSeconds (16) ends a turn at the first gap of 320 ms or more once it is\n that long. Raise it, together with maxUtteranceSeconds, when you want one\n recording per turn.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Finding the end of a spoken turn in a browser","lvl3":""}},
4545
4546
  {"objectID":"dee2eadc8e2a8712fe874329eae3639423ba11bb01631e21956abde47b3c7a3f","title":"CLI","url":"/docs/features/transcribe#cli","content":"The text output is the transcript, then a dim line with the engine, the\nlanguage (detected or unsure), the audio length, each layer's time and the\nsteps. --format json prints the whole TranscribeResult (one event per line\nwith --stream); --format srt|vtt builds subtitle cues from the segments, or\nfrom the word timings. --stream decodes the file to 16 kHz mono PCM16 (WAV in\nprocess, anything else through ffmpeg) and runs it through\ntranscribeStream(). Credentials are env-only, as for every CLI command. The\nfull flag table is in the CLI reference.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"CLI","lvl3":""}},
4546
4547
  {"objectID":"3529c7278a91963a4075c1f8b880ed143b9276ea52089e84639f7c658685bae8","title":"Server routes","url":"/docs/features/transcribe#server-routes","content":"createAllRoutes() / registerAllRoutes() mount two routes on every adapter\n(Hono, Express, Fastify, Koa); createTranscribeRoutes(basePath, options)\nmounts them on their own. Neither accepts credentials: engines use the\nserver's own configuration, and a credentials field in a body is ignored.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Server routes","lvl3":""}},
4547
4548
  {"objectID":"081502d8e5cd1a1c0f622a7d6118ac263dc88c9d07d8ef96402d71b4957a7172","title":"POST /api/agent/transcribe","url":"/docs/features/transcribe#post-apiagenttranscribe","content":"JSON body with exactly one audio source:\n\n| Source | Rules |\n| ----------- | ------------------------------------------------------------------------------------------------------------------------------- |\n| audio | Base64, or a data:audio/...;base64, URL. Bounded by the adapter's JSON body limit (bodyParser.jsonLimit, 10 MB by default). |\n| audioUrl | An http(s) URL the server downloads through the SSRF guard (private addresses and redirects refused), capped in size. |\n| audioPath | A path on the server. Refused by default; allowed only inside the directories in transcribe.allowedAudioRoots. |\n\nThe response is the TranscribeResult, in the adapters' usual\n{ data, metadata } envelope. Errors use the usual error shape: 400 for an\ninvalid body or an unsupported provider, language or format, 403 for a refused\naudioPath, 413 for audio over the limit, 500 for an engine failure.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"POST /api/agent/transcribe","lvl3":""}},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "12.58.1",
3
+ "version": "12.59.0",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002/call) for routing, tool selection and context budgeting. MCP-native (4 transports), voice TTS/STT/realtime, RAG, agents, memory, compaction, 9 observability exporters. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · TypeSafe Jev and more.",
6
6
  "author": {
@@ -399,6 +399,11 @@
399
399
  "import": "./dist/voice/index.js",
400
400
  "default": "./dist/voice/index.js"
401
401
  },
402
+ "./voice/endpointer": {
403
+ "types": "./dist/voice/streaming/endpointer.d.ts",
404
+ "import": "./dist/voice/streaming/endpointer.js",
405
+ "default": "./dist/voice/streaming/endpointer.js"
406
+ },
402
407
  "./music": {
403
408
  "types": "./dist/music/index.d.ts",
404
409
  "import": "./dist/music/index.js",