From 88a456d0b159e0b5327e8e6449c7878abb5b1f3e Mon Sep 17 00:00:00 2001 From: Damien Murphy Date: Wed, 9 Apr 2025 16:50:17 -0700 Subject: [PATCH 1/6] Add Nova 3 and Keyterm support --- src/common/options.rs | 160 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/src/common/options.rs b/src/common/options.rs index 79e35084..7e73e0a6 100644 --- a/src/common/options.rs +++ b/src/common/options.rs @@ -26,6 +26,7 @@ pub struct Options { search: Vec, replace: Vec, keywords: Vec, + keyterms: Vec, keyword_boost_legacy: Option, utterances: Option, tags: Vec, @@ -195,6 +196,17 @@ impl fmt::Display for Endpointing { #[derive(Debug, PartialEq, Eq, Clone, Hash)] #[non_exhaustive] pub enum Model { + /// Recommended for challenging audio. + /// Recommended for most use cases. + /// + /// Nova-3 expands on Nova-2's advancements with speech-specific + /// optimizations to the underlying Transformer architecture, advanced + /// data curation techniques, and a multi-stage training methodology. + /// These changes yield reduced word error rate (WER) and enhancements + /// to entity recognition (i.e. proper nouns, alphanumerics, etc.), + /// punctuation, and capitalization and Keyterms. + Nova3, + /// Recommended for readability and Deepgram's lowest word error rates. /// Recommended for most use cases. /// @@ -703,6 +715,7 @@ impl OptionsBuilder { search: Vec::new(), replace: Vec::new(), keywords: Vec::new(), + keyterms: Vec::new(), keyword_boost_legacy: None, utterances: None, tags: Vec::new(), @@ -1911,6 +1924,67 @@ impl OptionsBuilder { self } + /// Set the Keyterms feature. + /// + /// Calling this when already set will append to the existing keyterms, not overwrite them. + /// + /// See the [Deepgram Keyterms feature docs][docs] for more info. + /// + /// [docs]: https://developers.deepgram.com/docs/keyterm + /// + /// # Examples + /// + /// ``` + /// # use deepgram::common::options::Options; + /// # + /// let options = Options::builder() + /// .keyterms(["hello", "world"]) + /// .build(); + /// ``` + /// + /// ``` + /// # use deepgram::common::options::Options; + /// # + /// let options1 = Options::builder() + /// .keyterms(["hello"]) + /// .keyterms(["world"]) + /// .build(); + /// + /// let options2 = Options::builder() + /// .keyterms(["hello", "world"]) + /// .build(); + /// + /// assert_eq!(options1, options2); + /// ``` + pub fn keyterms<'a>(mut self, keyterms: impl IntoIterator) -> Self { + self.0.keyterms.extend(keyterms.into_iter().map(String::from)); + self + } + + /// Add a single keyterm. + /// + /// This is a convenience method for adding a single keyterm. + /// For multiple keyterms, use [`OptionsBuilder::keyterms`] instead. + /// + /// See the [Deepgram Keyterms feature docs][docs] for more info. + /// + /// [docs]: https://developers.deepgram.com/docs/keyterm + /// + /// # Examples + /// + /// ``` + /// # use deepgram::common::options::Options; + /// # + /// let options = Options::builder() + /// .keyterm("hello") + /// .keyterm("world") + /// .build(); + /// ``` + pub fn keyterm(mut self, keyterm: impl Into) -> Self { + self.0.keyterms.push(keyterm.into()); + self + } + /// Finish building the [`Options`] object. pub fn build(self) -> Options { self.0 @@ -1958,6 +2032,7 @@ impl Serialize for SerializableOptions<'_> { search, replace, keywords, + keyterms, keyword_boost_legacy, utterances, tags, @@ -2182,6 +2257,10 @@ impl Serialize for SerializableOptions<'_> { seq.serialize_element(&("callback_method", callback_method.as_str()))?; } + for element in keyterms { + seq.serialize_element(&("keyterm", element))?; + } + seq.end() } } @@ -2189,6 +2268,7 @@ impl Serialize for SerializableOptions<'_> { impl AsRef for Model { fn as_ref(&self) -> &str { match self { + Self::Nova3 => "nova-3", Self::Nova2 => "nova-2", Self::Nova => "nova", Self::Enhanced => "enhanced", @@ -2985,4 +3065,84 @@ mod serialize_options_tests { "paragraphs=true", ); } + + #[test] + fn keyterms_serialization() { + check_serialization(&Options::builder().keyterms([]).build(), ""); + + check_serialization( + &Options::builder().keyterms(["hello"]).build(), + "keyterm=hello", + ); + + check_serialization( + &Options::builder().keyterms(["hello", "world"]).build(), + "keyterm=hello&keyterm=world", + ); + + // Test URL encoding of spaces + check_serialization( + &Options::builder().keyterm("hello world").build(), + "keyterm=hello+world", + ); + + // Test with other features + check_serialization( + &Options::builder() + .model(Model::Nova3) + .language(Language::en) + .keyterms(["hello", "world"]) + .punctuate(true) + .build(), + "model=nova-3&language=en&punctuate=true&keyterm=hello&keyterm=world", + ); + + // Test with multiple words per keyterm + check_serialization( + &Options::builder() + .keyterms(["hello world", "rust programming"]) + .build(), + "keyterm=hello+world&keyterm=rust+programming", + ); + } + + #[test] + fn keyterms() { + check_serialization(&Options::builder().keyterms([]).build(), ""); + + check_serialization( + &Options::builder().keyterms(["hello"]).build(), + "keyterm=hello", + ); + + check_serialization( + &Options::builder().keyterms(["hello", "world"]).build(), + "keyterm=hello&keyterm=world", + ); + + // Test URL encoding of spaces + check_serialization( + &Options::builder().keyterm("hello world").build(), + "keyterm=hello+world", + ); + + // Test with other features + check_serialization( + &Options::builder() + .model(Model::Nova3) + .language(Language::en) + .keyterms(["hello", "world"]) + .punctuate(true) + .build(), + "model=nova-3&language=en&punctuate=true&keyterm=hello&keyterm=world", + ); + + // Test with multiple words per keyterm + check_serialization( + &Options::builder() + .keyterms(["hello world", "rust programming"]) + .build(), + "keyterm=hello+world&keyterm=rust+programming", + ); + } } From 1ae2085007c3e971ea246ace3643c34d1f68e07d Mon Sep 17 00:00:00 2001 From: Damien Murphy Date: Wed, 9 Apr 2025 16:57:16 -0700 Subject: [PATCH 2/6] fix linter error --- src/common/options.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common/options.rs b/src/common/options.rs index 7e73e0a6..e8fbb8af 100644 --- a/src/common/options.rs +++ b/src/common/options.rs @@ -1957,7 +1957,9 @@ impl OptionsBuilder { /// assert_eq!(options1, options2); /// ``` pub fn keyterms<'a>(mut self, keyterms: impl IntoIterator) -> Self { - self.0.keyterms.extend(keyterms.into_iter().map(String::from)); + self.0 + .keyterms + .extend(keyterms.into_iter().map(String::from)); self } From 5b4c1da4e6d934fd90939e664df607d2a1dca3a4 Mon Sep 17 00:00:00 2001 From: Damien Murphy Date: Wed, 9 Apr 2025 17:01:41 -0700 Subject: [PATCH 3/6] bump SDK version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index d03a1e04..8c330e2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "deepgram" -version = "0.6.6" +version = "0.6.7" authors = ["Deepgram "] edition = "2021" description = "Community Rust SDK for Deepgram's automated speech recognition APIs." From 01aa8d9d309ff2f952f0c9a7b694c56972d2d60a Mon Sep 17 00:00:00 2001 From: Damien Murphy Date: Wed, 9 Apr 2025 18:15:29 -0700 Subject: [PATCH 4/6] remove single keyterm functions in favor of always passing an array --- src/common/options.rs | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/src/common/options.rs b/src/common/options.rs index e8fbb8af..ac62e9a4 100644 --- a/src/common/options.rs +++ b/src/common/options.rs @@ -1963,30 +1963,6 @@ impl OptionsBuilder { self } - /// Add a single keyterm. - /// - /// This is a convenience method for adding a single keyterm. - /// For multiple keyterms, use [`OptionsBuilder::keyterms`] instead. - /// - /// See the [Deepgram Keyterms feature docs][docs] for more info. - /// - /// [docs]: https://developers.deepgram.com/docs/keyterm - /// - /// # Examples - /// - /// ``` - /// # use deepgram::common::options::Options; - /// # - /// let options = Options::builder() - /// .keyterm("hello") - /// .keyterm("world") - /// .build(); - /// ``` - pub fn keyterm(mut self, keyterm: impl Into) -> Self { - self.0.keyterms.push(keyterm.into()); - self - } - /// Finish building the [`Options`] object. pub fn build(self) -> Options { self.0 @@ -3084,7 +3060,7 @@ mod serialize_options_tests { // Test URL encoding of spaces check_serialization( - &Options::builder().keyterm("hello world").build(), + &Options::builder().keyterms(["hello world"]).build(), "keyterm=hello+world", ); @@ -3124,7 +3100,7 @@ mod serialize_options_tests { // Test URL encoding of spaces check_serialization( - &Options::builder().keyterm("hello world").build(), + &Options::builder().keyterms(["hello world"]).build(), "keyterm=hello+world", ); From a0947fd3dcde0b2fb34c0299ea79b78293b0d215 Mon Sep 17 00:00:00 2001 From: Brent George Date: Thu, 10 Apr 2025 19:51:36 -0400 Subject: [PATCH 5/6] bump version to 0.7.0 with new features enabled --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8c330e2d..e87e80a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "deepgram" -version = "0.6.7" +version = "0.7.0" authors = ["Deepgram "] edition = "2021" description = "Community Rust SDK for Deepgram's automated speech recognition APIs." From 853448480c767c049f8d878bf81043adcff9315d Mon Sep 17 00:00:00 2001 From: Brent George Date: Thu, 10 Apr 2025 20:05:29 -0400 Subject: [PATCH 6/6] Revert "bump version to 0.7.0 with new features enabled" This reverts commit a0947fd3dcde0b2fb34c0299ea79b78293b0d215. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e87e80a8..8c330e2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "deepgram" -version = "0.7.0" +version = "0.6.7" authors = ["Deepgram "] edition = "2021" description = "Community Rust SDK for Deepgram's automated speech recognition APIs."