Commit Graph
100 Commits
Author SHA1 Message Date
Dave Horton 12e3364461 speechify 2026-09-30 23:03:54 -04:00
Dave Horton 18917f49ff 1.0.19 2026-09-29 14:22:33 -04:00
Dave HortonandClaude Opus 5.5 fa705694e1 feat(tts): add kugelaudio as a TTS vendor (#163)
Streaming returns a say: url for the mediajam dialect; the cache render POSTs
/v1/tts/generate for raw 8 kHz PCM (r8). Language is reduced to its primary
subtag and dropped when KugelAudio does not support it.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 14:21:41 -04:00
Dave HortonandClaude Opus 5 89fe0b87e9 fix: stop the RoleArn synth test printing AWS credentials into CI logs (#161)
With renderForCaching unset, synthPolly returns the mediajam streaming params
string, and lib/synth-audio.js:337-340 embeds accessKeyId, secretAccessKey and
sessionToken in it. The test interpolated that value into its assertion message,
so run 32995180996 printed live (1 hour) AWS credentials into a public build log.

Every other synth test in this file passes renderForCaching: true; this one was
the only exception. It now does the same, and the assertion no longer interpolates
opts.filePath at all, so the streaming params string cannot leak this way again.

Latent since the test was written -- it only surfaced once AWS_ROLE_ARN was wired
up and the test actually ran.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 13:44:05 -04:00
Dave HortonandClaude Opus 5 b928820906 ci: authenticate to AWS via GitHub OIDC instead of stored access keys (#160)
* ci: authenticate to AWS via GitHub OIDC instead of stored access keys

CI held a long-lived AWS access key as repository secrets. This replaces it with
a short-lived credential obtained through the GitHub OIDC provider, so no AWS key
is stored in the repo at all.

The tests could not simply inherit the OIDC credentials. They passed
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY explicitly, which routes
lib/get-aws-sts-token.js down its accessKeyId branch and calls GetSessionToken --
and AWS rejects GetSessionToken when it is called with session credentials.

test/aws-credentials.js centralises the decision. When AWS_SESSION_TOKEN is present
the credentials are temporary and only the region is passed, so the SDK's default
credential provider chain is used. Static keys still work unchanged, which keeps
local run-tests.sh working and also lets it run off an 'aws sso login' session with
no credentials in the file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* test: supply a cache key when AWS credentials come from the default chain

getAwsAuthToken derives its cache key as roleArn || accessKeyId || speech_credential_sid.
With temporary credentials the test passes none of those, so makeAwsKey received
undefined and hash.update() threw ERR_INVALID_ARG_TYPE.

Production never hits this: the instance-profile path always carries a
speech_credential_sid from the database, which is exactly what the comment above
that line describes. The test now supplies one the same way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* ci: reference the CI role via secret rather than inlining the account id

speech-utils is public, so the role ARN (and with it the AWS account id) should not
be committed. It now comes from the AWS_ROLE_ARN secret, which also feeds the
'AWS speech synth tests by RoleArn' test -- previously always skipped, so the
AssumeRole credential path had no coverage here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* test: give the AWS RoleArn synth test its own cache key

The RoleArn test synthesized the same vendor/voice/language/text as the plain AWS
synth test that runs before it, so it hit that test's cache entry, servedFromCache
came back true and the !servedFromCache assertion failed.

Latent since the test was written -- it never ran, because AWS_ROLE_ARN was never
supplied. Wiring the secret in activated it and exposed the collision. Distinct text
makes the test independent of execution order.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 13:38:32 -04:00
Dave Horton f4c3c7dc8b 1.0.18 2026-08-23 13:12:37 -04:00
Dave HortonandClaude Opus 5 a32f71ac5a feat: add fishaudio (Fish Audio) TTS support (#159)
Adds synthFishaudio with both arms: the say: streaming url consumed by the
mediajam dialect, and a POST /v1/tts cache render. The render asks for raw pcm
at 8k and returns extension r8 because fish's wav output carries a placeholder
RIFF size, the same problem gradium has.

Fish is a voice-cloning vendor, so the voice is a reference_id; the sentinel
'default' means send none and use fish's own default voice.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 13:11:59 -04:00
Dave HortonandClaude Opus 5 c8850998b5 fix(tts): use a current nineninesix voice id in the synth test (#158)
The vendor replaced its voice catalog and now rejects unknown ids, so
the env-gated test failed whenever NINENINESIX_API_KEY was set.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 12:19:59 -04:00
Dave Horton e8b2009d29 1.0.17 2026-08-10 16:45:32 -04:00
Dave HortonandClaude Opus 5 27e07bb551 fix(tts): forward gradium json_config to the streaming path (#157)
synthGradium destructured json_config from options but only forwarded
pronunciation_id into the say: param block, so the setting could never
reach mediajam's streaming dialect — only the cache-render POST. The
say: parser is brace-aware, so a nested json object survives intact.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 16:45:07 -04:00
Dave Horton 33456b93d9 1.0.16 2026-08-08 23:07:43 -04:00
Dave HortonandClaude Opus 5 70e91b5057 test(inworld): gate the say: param test on INWORLD_API_KEY (#156)
The test I added in #155 ran unconditionally, which broke `npm test` without
credentials — the path husky's pre-commit hook takes, so `npm version patch`
could not commit.

Two causes, both addressed:

- no credential gate, unlike every other vendor test in this file. Now skips
  without INWORLD_API_KEY, and closes its redis client on that path so the
  run can still exit.
- it assumed streaming was enabled. The Google non-streaming test sets
  JAMBONES_DISABLE_TTS_STREAMING and, on its no-credentials skip path,
  deletes the env var WITHOUT clearing the require cache (unlike its finally
  block, which clears both) — so lib/config still held 'true' further down
  the file and synthInworld took the non-streaming branch, attempting a real
  vendor call. The test now re-requires with streaming enabled so it does not
  depend on what ran before it.

Verified both ways: skips and exits 0 with no key; 11/11 with a key even
under the leaked state. Re-introducing the #155 bug still fails 3 assertions,
so the regression value is intact.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 23:06:52 -04:00
Dave HortonandClaude Opus 5 c066840f85 fix(inworld): read pitch and speakingRate from audioConfig in the say: params (#155)
The streaming say: path guarded on opts.audioConfig?.pitch and
opts.audioConfig?.speakingRate but interpolated opts.pitch and
opts.speakingRate, which are undefined — so anyone setting them under
audioConfig (what the docs and the portal defaults tell you to do) got
'pitch=undefined,speakingRate=undefined' on the wire and their setting
silently dropped.

Adds a test for the say: params that needs no credentials, since the
streaming branch builds the path without calling the vendor.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 22:49:50 -04:00
Dave Horton d89457f67d 1.0.15 2026-08-06 10:23:47 -04:00
Dave HortonandClaude Opus 5 3c15976669 fix(deps): remove junk "23" dependency (#154)
"23": "^0.0.0" is not a real dependency - it is an empty placeholder
package (0.0.0, no deps, unrelated third-party maintainer) that landed
here from a stray npm install. Nothing in the package references it.

Beyond the noise, it is a small supply-chain liability: a dependency on
a squatted single-number name owned by nobody we know, shipped to every
consumer of speech-utils.

Lint passes; full test suite passes 105/105 with live vendor credentials.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 10:23:31 -04:00
Dave Horton 70abb04941 1.0.14 2026-08-06 10:13:51 -04:00
Dave HortonandClaude Opus 5 724af7fcab fix(deps): drop unused undici dependency (#153)
undici was declared as a direct dependency but is never required
anywhere in this package - grep across index.js, lib/ and stubs/ finds
no reference to undici, ProxyAgent, setGlobalDispatcher or Dispatcher.
The one HTTP call in lib/synth-audio.js uses the global fetch, and
Azure proxy support goes through the SDK's own setProxy plus the
http_proxy_ip/http_proxy_port params.

Removing it clears all seven open undici advisories from npm audit for
this package and its consumers, and stops speech-utils pulling a
duplicate undici 7.x into trees where the consumer already depends on
undici 8 (feature-server does).

Lint passes; full test suite passes 105/105 with live vendor credentials.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 10:13:31 -04:00
Dave Horton c0a79090c2 1.0.13 2026-08-06 10:04:26 -04:00
Dave HortonandClaude Opus 5 7a9a3e2468 fix(deps): bump microsoft-cognitiveservices-speech-sdk to ^1.51.0 (#152)
The Azure speech SDK was pinned to exactly 1.38.0 since the initial
commit. It pulls in uuid <11.1.1, which carries GHSA-w5hq-g745-h8pq
(missing buffer bounds check in v3/v5/v6 when buf is provided). The
advisory covers Azure SDK 1.14.0-1.50.0; 1.51.0 clears it.

Loosened the exact pin to a caret range so future patches come in
without another PR. The SDK surface used here (SpeechConfig,
SpeechSynthesizer, ResultReason, CancellationDetails,
SpeechSynthesisOutputFormat) is unchanged in 1.51.0.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 10:03:59 -04:00
Dave Horton ab2b3f7fb2 1.0.12 2026-08-04 09:04:50 -04:00
Dave HortonandClaude Opus 5 e848d0276e feat(tts): add gradium as a TTS vendor (#151)
Streaming arm returns a say: url for the mediajam dialect; the cache-render
arm posts to /api/post/speech/tts with only_audio and pcm_8000, which is bare
r8 samples and avoids gradium's streaming wav header (0xffffffff RIFF size).

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 09:02:07 -04:00
Dave Horton d2447d477d 1.0.11 2026-08-03 12:04:47 -04:00
Dave HortonandClaude Opus 5 ec8bbacc2c feat(tts): add nineninesix.ai synthesis (#150)
Streaming goes through mediajam's say: url; the cache render posts to
/tts/bytes for wav, since the service rejects mp3.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 12:03:52 -04:00
Dave Horton 9694714a7f 1.0.10 2026-07-28 20:59:05 -04:00
Dave Horton 04d1fb548b 1.0.9 2026-07-21 06:52:05 -04:00
Dave Horton 4cfa286242 1.0.8 2026-07-05 17:42:09 -04:00
Dave Horton 12a121672d 1.0.7 2026-07-03 07:12:20 -04:00
Dave Horton c47b4883c7 1.0.6 2026-06-17 16:20:30 -04:00
Dave HortonandClaude Opus 4.8 7d076bb8b4 chore: deprecate + remove verbio, nuance, playht speech vendor support (#144)
* chore: deprecate and remove verbio, nuance speech vendor support

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: also deprecate and remove PlayHT speech vendor

PlayHT was acquired and no longer provides the service.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 16:20:00 -04:00
Dave HortonandClaude Opus 4.8 142323a151 fix(synth-audio): include the Polly VoiceId in the aws say: url
synthPolly received voice but never emitted it into the say:{...} url
(unlike synthMicrosoft, which includes voice=). Polly's SynthesizeSpeech
requires a VoiceId, so the media-server-native (say:-url) Polly path had no
way to pick a voice. Add voice= to the params.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 22:31:57 -04:00
Dave Horton d176a644fe 1.0.4 2026-06-06 10:44:11 +02:00
Dave HortonandClaude Opus 4.5 4f430b9785 update publish workflow to use actions v4
Fixes npm warning about deprecated always-auth config by updating
setup-node from v3 to v4.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-06-03 08:51:56 -04:00
Dave Horton 18c658d20c 1.0.3 2026-06-03 07:27:44 -04:00
Dave Horton 062608cf13 update lock file 2026-06-03 07:27:28 -04:00
Dave Horton 04bb85ef81 1.0.1 2026-03-25 10:08:57 -04:00
Dave Horton c123f19898 remove ibm speech since it is not used (to my knowledge) and has dependencies with vulnerabilities (#141) 2026-03-25 10:08:30 -04:00
Dave Horton 305695d068 0.2.30 2026-01-22 08:03:44 -05:00
Dave Horton 1477752d40 update dep 2026-01-22 08:03:24 -05:00
Dave Horton fbedfe947f vuln 2026-01-22 07:58:06 -05:00
Dave Horton ab88facd52 Merge pull request #139 from jambonz/feat/google_gemini_tts
google tts support api_mode
2026-01-22 07:52:04 -05:00
Dave Horton c5e0f256e6 0.2.28 2026-01-17 21:39:59 -05:00
Dave Horton d0378751ba Merge pull request #135 from jambonz/feat/gemini_tts
support gemini tts
2026-01-17 21:39:28 -05:00
Dave Horton 5f7e7458bb 0.2.27 2025-11-17 07:26:45 -05:00
Dave Horton f6714fb9e1 Merge pull request #134 from jambonz/fix/1628
fixed cartesia collect audio from stream
2025-11-13 07:15:51 -05:00
Dave Horton 8154944252 0.2.26 2025-10-30 07:08:47 -04:00
Dave Horton 16fe8dce01 0.2.25 2025-10-30 07:08:10 -04:00
Dave Horton 11a955500d Merge pull request #132 from jambonz/feat/sonic_3
cartesia support volume for sonic3
2025-10-30 07:07:15 -04:00
Dave Horton 4e336822a0 Merge pull request #131 from jambonz/feat/gh_fs_1384
support elevenlabs api_uri
2025-10-08 13:45:02 -04:00
Dave Horton 8d8195be9a 0.2.24 2025-10-03 08:54:14 -04:00
Dave Horton eb4e1a773f Merge pull request #130 from jambonz/feat/disableTtsCache
set write_cache_file = 0 when disableTtsCache
2025-10-03 02:21:57 -04:00
Dave Horton fdb56cbc77 Merge pull request #128 from jambonz/feat/custom_tts_stream
support custom tts Stream
2025-09-11 09:24:18 -04:00
Dave Horton ea1ab301d5 0.2.23 2025-09-10 22:53:45 -04:00
Dave Horton 0a4994c5a3 Merge pull request #129 from jambonz/fix/fd_1372
remove optimize_streaming_latency as default option for elevenlabs
2025-09-10 22:53:27 -04:00
Dave Horton f08efa49b1 0.2.22 2025-08-20 18:03:08 -04:00
Dave Horton 80eda37ef6 Merge pull request #126 from jambonz/feat/revamp-playback-id
use synth key as playback id
2025-08-20 18:02:35 -04:00
Dave Horton 7768e58b19 use synth key as playback id 2025-08-20 17:11:45 -04:00
Dave Horton 6efc99ad83 0.2.21 2025-08-20 10:59:40 -04:00
Dave Horton 127d01a8c1 add playback_id setting to additional tts vendors 2025-08-20 10:58:28 -04:00
Dave Horton 1900b26d8b 0.2.20 2025-08-20 10:01:01 -04:00
Dave Horton aa25a6f6d9 Merge pull request #125 from jambonz/feat/add-playback-id
add playback_id to say metadata
2025-08-20 10:00:37 -04:00
Dave Horton 8dfe17b600 add playback_id to say metadata 2025-08-20 08:58:46 -04:00
Dave Horton 5463e9f56e 0.2.19 2025-08-17 09:35:07 -04:00
Dave Horton 2eb36af650 Merge pull request #124 from jambonz/fix/aws_tts
support mod_aws_tts with engine parameter
2025-08-17 09:23:58 -04:00
Dave Horton b1b9c182a9 0.2.18 2025-08-14 08:17:02 -04:00
Dave Horton 15c77626fc Merge pull request #123 from jambonz/feat/mod_aws_tts
support mod_aws_tts
2025-08-14 08:16:32 -04:00
Dave Horton ab05976032 0.2.17 2025-08-13 07:41:24 -04:00
Dave Horton babd8abc51 Merge pull request #122 from jambonz/feat/resemble_tts_01
support resemble tts
2025-08-13 07:33:12 -04:00
Dave Horton 8a0c5e3dbd tag 2025-08-10 20:11:52 -04:00
Dave Horton d40e012138 Merge pull request #120 from jambonz/feat/resemble_tts
support resemble ai
2025-08-10 19:12:26 -04:00
Dave Horton 043642ea5f 0.2.15 2025-07-13 10:27:02 -04:00
Dave Horton 91ea9820f9 Merge pull request #119 from vdharashive/main
TMP_FOLDER configurable
2025-07-10 07:32:16 -04:00
Dave Horton 2608e149a8 0.2.14 2025-07-09 13:43:38 -04:00
Dave Horton d21289acd6 sec fix 2025-07-09 13:43:12 -04:00
Dave Horton a7b19e1d8a Merge pull request #117 from sathishkumarpa-Kore/PLAT-41939_2
Fix security vulnerability by upgrading ibm-watson to latest version
2025-07-09 13:42:01 -04:00
Dave Horton f311c21327 0.2.13 2025-06-26 08:02:24 -04:00
Dave Horton 535d0191da Merge pull request #115 from jambonz/feat/inworld_tts
support inworld tts
2025-06-26 08:01:23 -04:00
Dave Horton db135ee5ad 0.2.12 2025-06-11 11:08:34 +02:00
Dave Horton 5eac4c2ad8 Merge pull request #114 from vasudevanubrolu/feat/893-azure-ssml
Feat/893 azure ssml
2025-06-11 11:05:48 +02:00
Dave Horton 6fb6195b16 0.2.11 2025-05-27 10:09:01 -04:00
Dave Horton 2ff8587601 Merge pull request #113 from vasudevanubrolu/feat/893-azure-ssml
Feat/893 azure ssml
2025-05-27 10:08:48 -04:00
Dave Horton 0d98f73c43 0.2.10 2025-05-13 09:57:01 -04:00
Dave Horton 36670e0080 Merge pull request #111 from vasudevanubrolu/feat/864-playht-onprem
feat/864 playht on prem
2025-05-13 09:50:46 -04:00
Dave Horton 6e8271b2f6 0.2.9 2025-05-13 07:47:03 -04:00
Dave Horton 74a4938eb6 Merge pull request #112 from jambonz/feat/whisper_instructions
support openai whisper instructions
2025-05-13 07:46:34 -04:00
Dave Horton 7dc3bbdb01 0.2.8 2025-05-08 09:31:40 -04:00
Dave Horton f8f9de2645 Merge pull request #110 from jambonz/feat/rimlabs_arcana
support rimelabs arcana
2025-05-06 09:22:35 -04:00
Dave Horton fc211ab2e7 0.2.7 2025-04-28 19:31:59 -04:00
Dave Horton 536f8aab31 Merge pull request #109 from jambonz/feat/riva_tts
support riva tts stream
2025-04-28 19:31:30 -04:00
Dave Horton 53fe72d89e 0.2.6 2025-04-23 07:12:54 -04:00
Dave Horton e79c15c5da update version 2025-04-23 07:12:25 -04:00
Dave Horton b697bc5268 Merge pull request #108 from jambonz/feat/ell_tts_new_params
elevenlabs tts speed and pronunciation_dictionary_locators
2025-04-23 07:08:49 -04:00
Dave Horton 04080cc5ec 0.2.4 2025-03-19 21:48:31 -04:00
Dave Horton 3e5ab4af27 Merge pull request #107 from jambonz/update-deps
update undici
2025-03-19 21:48:02 -04:00
Dave Horton f06dddd2f7 update undici 2025-03-19 21:46:21 -04:00
Dave Horton 7b4a71f55d 0.2.3 2025-02-07 07:20:12 -05:00
Dave Horton d552b65618 Merge pull request #106 from jambonz/feat/rimelabs_voices
rimelabs support multiple model and languages
2025-02-07 07:19:47 -05:00
Dave Horton 199e502fbe 0.2.2 2025-02-03 08:14:15 -05:00
Dave Horton 6769779189 Merge pull request #105 from jambonz/fix/gh_1059
tts key should include model
2025-02-03 08:13:54 -05:00
Dave Horton 37fb045431 0.2.1 2024-12-18 22:16:43 -05:00
Dave Horton c328df67a2 major semver bump 2024-12-18 22:15:28 -05:00