@humeai/cli 0.0.10 → 0.0.11

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.
Files changed (3) hide show
  1. package/README.md +4 -0
  2. package/dist/index.js +95 -13
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -61,6 +61,7 @@ $ hume tts <text>
61
61
  --trailing-silence #0 Seconds of silence to add at the end (0.0-5.0, default is 0.35)
62
62
  --streaming Use streaming mode for TTS generation (default: true)
63
63
  --instant-mode Enable ultra-low latency mode for significantly faster generation (requires streaming=true, a voice, and incurs 10% higher cost)
64
+ --curl Generate curl command instead of making the API request
64
65
 
65
66
  ━━━ Details ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
66
67
 
@@ -110,6 +111,9 @@ $ hume tts "Hello world" -v narrator --instant-mode
110
111
  Setting instant mode in your config (always enable)
111
112
  $ hume config set tts.instantMode true
112
113
 
114
+ Generating curl command instead of making API request
115
+ $ hume tts "Hello world" -v narrator --curl
116
+
113
117
  ## Voice Management
114
118
 
115
119
  Save a voice from a previous generation
package/dist/index.js CHANGED
@@ -50425,6 +50425,33 @@ var getHumeClient = (opts) => {
50425
50425
  environment: opts.baseUrl ?? "https://api.hume.ai"
50426
50426
  });
50427
50427
  };
50428
+ var getApiKeyProvenance = (opts, globalConfig, session, env) => {
50429
+ if (opts.apiKey) {
50430
+ return { source: "flag", value: opts.apiKey };
50431
+ }
50432
+ if (env.HUME_API_KEY) {
50433
+ return { source: "env", value: env.HUME_API_KEY };
50434
+ }
50435
+ if (session.apiKey) {
50436
+ return { source: "session", value: session.apiKey };
50437
+ }
50438
+ if (globalConfig.apiKey) {
50439
+ return { source: "global", value: globalConfig.apiKey };
50440
+ }
50441
+ return null;
50442
+ };
50443
+ var formatApiKeyForCurl = (provenance) => {
50444
+ switch (provenance.source) {
50445
+ case "flag":
50446
+ return provenance.value;
50447
+ case "env":
50448
+ return "$HUME_API_KEY";
50449
+ case "global":
50450
+ return "$(hume config show | jq '.apiKey')";
50451
+ case "session":
50452
+ return "$(hume session show | jq '.apiKey')";
50453
+ }
50454
+ };
50428
50455
 
50429
50456
  // src/config.ts
50430
50457
  var CONFIG_FILE = "config.json";
@@ -50443,6 +50470,7 @@ var configValidators = {
50443
50470
  "tts.trailingSilence": t.cascade(t.isNumber(), t.isInInclusiveRange(0, 5)),
50444
50471
  "tts.streaming": t.isBoolean(),
50445
50472
  "tts.instantMode": t.isBoolean(),
50473
+ "tts.modelVersion": t.isEnum(["1", "2"]),
50446
50474
  json: t.isBoolean(),
50447
50475
  pretty: t.isBoolean(),
50448
50476
  apiKey: t.isString()
@@ -50618,7 +50646,7 @@ var resetGlobalConfig = clearConfig("global");
50618
50646
  // package.json
50619
50647
  var package_default = {
50620
50648
  name: "@humeai/cli",
50621
- version: "0.0.10",
50649
+ version: "0.0.11",
50622
50650
  module: "index.ts",
50623
50651
  type: "module",
50624
50652
  description: "CLI for Hume.ai's OCTAVE expressive TTS API",
@@ -50796,6 +50824,7 @@ var withStdinAudioPlayer = async (customCommand, f) => {
50796
50824
  };
50797
50825
 
50798
50826
  // src/tts.ts
50827
+ var import_serialization = __toESM(require_serialization(), 1);
50799
50828
  var calculateOutputOpts = (opts) => {
50800
50829
  if (opts.numGenerations > 1 && opts.outputFilePath) {
50801
50830
  throw new Error("Unexpected: cannot specify both --num-generations and --output-file-path");
@@ -50873,7 +50902,8 @@ class Tts {
50873
50902
  speed: null,
50874
50903
  trailingSilence: null,
50875
50904
  streaming: true,
50876
- instantMode: false
50905
+ instantMode: false,
50906
+ modelVersion: null
50877
50907
  };
50878
50908
  async writeFiles(opts, generations) {
50879
50909
  if (opts.type === "path") {
@@ -50985,6 +51015,8 @@ class Tts {
50985
51015
  const trailingSilence = osgd("trailingSilence").item;
50986
51016
  const streaming = osgd("streaming").item;
50987
51017
  const instantMode = osgd("instantMode").item;
51018
+ const modelVersion = osgd("modelVersion").item;
51019
+ const requestJson = opts.requestJson ?? null;
50988
51020
  const voiceName_ = osgd("voiceName");
50989
51021
  const voiceId_ = osgd("voiceId");
50990
51022
  let voiceName = voiceName_.item;
@@ -51015,7 +51047,9 @@ class Tts {
51015
51047
  speed,
51016
51048
  trailingSilence,
51017
51049
  streaming,
51018
- instantMode
51050
+ instantMode,
51051
+ modelVersion,
51052
+ requestJson
51019
51053
  };
51020
51054
  }
51021
51055
  async readStdin() {
@@ -51035,6 +51069,12 @@ class Tts {
51035
51069
  async synthesize(rawOpts) {
51036
51070
  const { session, globalConfig, env, reporter, hume } = await this.getSettings(rawOpts);
51037
51071
  const opts = Tts.resolveOpts(env, globalConfig, session, rawOpts);
51072
+ if (!opts.text && !opts.requestJson) {
51073
+ throw new Error("Either text parameter or --request-json must be provided");
51074
+ }
51075
+ if (opts.text && opts.requestJson) {
51076
+ throw new Error("Cannot specify both text parameter and --request-json. Use one or the other.");
51077
+ }
51038
51078
  const outputOpts = calculateOutputOpts(opts);
51039
51079
  if (opts.presetVoice) {
51040
51080
  reporter.warn("Please use --provider HUME_AI instead of --preset-voice. --preset-voice will be removed in a future version");
@@ -51045,19 +51085,33 @@ class Tts {
51045
51085
  }
51046
51086
  const utterance = calculateUtterance({
51047
51087
  ...opts,
51048
- text,
51088
+ text: text || "",
51049
51089
  speed: opts.speed,
51050
51090
  trailingSilence: opts.trailingSilence,
51051
51091
  provider: opts.provider
51052
51092
  });
51053
- const tts = {
51054
- utterances: [utterance],
51055
- numGenerations: outputOpts.numGenerations,
51056
- format: { type: opts.format },
51057
- version: opts.modelVersion ?? undefined
51058
- };
51059
- await this.maybeAddContext(opts, tts);
51060
- if (opts.instantMode) {
51093
+ let tts;
51094
+ if (opts.requestJson) {
51095
+ try {
51096
+ tts = JSON.parse(String(opts.requestJson));
51097
+ debug2("Using hardcoded request body: %O", JSON.stringify(tts, null, 2));
51098
+ } catch (error) {
51099
+ throw new Error(`Invalid JSON in --request-json: ${error instanceof Error ? error.message : "Unknown error"}`);
51100
+ }
51101
+ } else {
51102
+ const baseTts = {
51103
+ utterances: [utterance],
51104
+ numGenerations: outputOpts.numGenerations,
51105
+ format: { type: opts.format }
51106
+ };
51107
+ if (opts.modelVersion !== null) {
51108
+ tts = { ...baseTts, version: opts.modelVersion };
51109
+ } else {
51110
+ tts = baseTts;
51111
+ }
51112
+ await this.maybeAddContext(opts, tts);
51113
+ }
51114
+ if (opts.instantMode && !opts.requestJson) {
51061
51115
  if (!opts.streaming) {
51062
51116
  throw new Error("Instant mode requires streaming to be enabled");
51063
51117
  }
@@ -51072,6 +51126,9 @@ class Tts {
51072
51126
  if (!hume) {
51073
51127
  throw new ApiKeyNotSetError;
51074
51128
  }
51129
+ if (opts.curl) {
51130
+ return this.generateCurlCommand(opts, env, globalConfig, session, reporter, tts);
51131
+ }
51075
51132
  if (opts.streaming) {
51076
51133
  return this.synthesizeStreaming(reporter, tts, hume, opts, outputOpts);
51077
51134
  }
@@ -51172,6 +51229,24 @@ class Tts {
51172
51229
  reporter.json({ result, written_files: writtenFiles });
51173
51230
  await this.playAudios(opts.play, writtenFiles, reporter, opts.playCommand ?? null);
51174
51231
  }
51232
+ async generateCurlCommand(opts, env, globalConfig, session, reporter, tts) {
51233
+ const apiKeyProvenance = getApiKeyProvenance(opts, globalConfig, session, env);
51234
+ if (!apiKeyProvenance) {
51235
+ throw new ApiKeyNotSetError;
51236
+ }
51237
+ const baseUrl = opts.baseUrl ?? env.HUME_BASE_URL ?? session.baseUrl ?? globalConfig.baseUrl ?? "https://api.hume.ai";
51238
+ const apiKey = formatApiKeyForCurl(apiKeyProvenance);
51239
+ const endpoint = opts.streaming ? "/v0/tts/stream/json" : "/v0/tts";
51240
+ const url = `${baseUrl}${endpoint}`;
51241
+ const serialized = import_serialization.default.tts.PostedTts.jsonOrThrow(tts);
51242
+ const curlCommand = [
51243
+ `curl "${url}"`,
51244
+ ` -H "X-Hume-Api-Key: ${apiKey}"`,
51245
+ ` --json '${JSON.stringify(serialized)}'`
51246
+ ].join(" \\\n");
51247
+ reporter.info("Generated curl command:");
51248
+ console.log(curlCommand);
51249
+ }
51175
51250
  }
51176
51251
 
51177
51252
  // src/index.ts
@@ -51269,6 +51344,7 @@ var usageDescriptions = {
51269
51344
  "tts.streaming": "Use streaming mode for TTS generation (default: true)",
51270
51345
  "tts.instantMode": "Enable ultra-low latency mode for significantly faster generation (requires streaming=true, a voice, and incurs 10% higher cost)",
51271
51346
  "tts.modelVersion": "Either '1' for Octave 1 or '2' for Octave 2.",
51347
+ "tts.curl": "Generate curl command instead of making the API request",
51272
51348
  apiKey: "Override the default API key",
51273
51349
  json: "Output in JSON format",
51274
51350
  pretty: "Output in human-readable format"
@@ -51571,7 +51647,7 @@ class TtsCommand extends Command2 {
51571
51647
  }), {
51572
51648
  usage: `$ hume tts <text>`
51573
51649
  });
51574
- text = exports_options.String({ required: true, name: "text" });
51650
+ text = exports_options.String({ required: false, name: "text" });
51575
51651
  description = exports_options.String("-d,--description", {
51576
51652
  description: usageDescriptions["tts.description"]
51577
51653
  });
@@ -51647,6 +51723,12 @@ class TtsCommand extends Command2 {
51647
51723
  description: usageDescriptions["tts.modelVersion"],
51648
51724
  validator: t2.isEnum(["1", "2"])
51649
51725
  });
51726
+ requestJson = exports_options.String("--request-json", {
51727
+ description: "Override the request body with a hardcoded JSON string instead of generating it from options"
51728
+ });
51729
+ curl = exports_options.Boolean("--curl", {
51730
+ description: usageDescriptions["tts.curl"]
51731
+ });
51650
51732
  async execute() {
51651
51733
  const tts = new Tts;
51652
51734
  await tts.synthesize(this);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humeai/cli",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "description": "CLI for Hume.ai's OCTAVE expressive TTS API",