Initial commit

This commit is contained in:
Slavi Pantaleev
2024-09-12 13:44:06 +03:00
commit 946aa9d9e9
220 changed files with 26033 additions and 0 deletions

View File

@@ -0,0 +1,141 @@
#[cfg(test)]
mod tests;
mod speech_to_text;
mod text_generation;
mod text_to_speech;
use crate::{
agent::{AgentPurpose, PublicIdentifier},
controller::ControllerType,
strings,
};
use super::controller_type::{
ConfigControllerType, ConfigSettingRelatedControllerType, SettingsStorageSource,
};
pub fn determine_controller(text: &str) -> ControllerType {
if text.starts_with("status") {
return ControllerType::Config(ConfigControllerType::Status);
}
// Someone pasted our instructions verbatim.
if text.strip_prefix("CONFIG_TYPE").is_some() {
return ControllerType::Error(strings::cfg::error_config_type_not_replaced());
}
if let Some(remaining_text) = text.strip_prefix("room ") {
return match do_determine_controller(remaining_text.trim()) {
Ok(handler) => ControllerType::Config(ConfigControllerType::SettingsRelated(
SettingsStorageSource::Room,
handler,
)),
Err(controller_type) => controller_type,
};
}
if let Some(remaining_text) = text.strip_prefix("global ") {
return match do_determine_controller(remaining_text.trim()) {
Ok(handler) => ControllerType::Config(ConfigControllerType::SettingsRelated(
SettingsStorageSource::Global,
handler,
)),
Err(controller_type) => controller_type,
};
}
ControllerType::Config(ConfigControllerType::Help)
}
fn do_determine_controller(
text: &str,
) -> Result<ConfigSettingRelatedControllerType, ControllerType> {
if let Some(purpose_str) = text.strip_prefix("handler") {
let purpose_str = purpose_str.trim();
if purpose_str.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_invocation_incorrect_more_values_expected().to_owned(),
));
}
let Some(purpose) = AgentPurpose::from_str(purpose_str) else {
return Err(ControllerType::Error(
strings::agent::purpose_unrecognized(purpose_str).to_owned(),
));
};
return Ok(ConfigSettingRelatedControllerType::GetHandler(purpose));
}
if let Some(remaining_text) = text.strip_prefix("set-handler") {
// Something like:
// - `PURPOSE ID`
// - `PURPOSE`
let remaining_text = remaining_text.trim();
if remaining_text.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_invocation_incorrect_more_values_expected().to_owned(),
));
}
// This will be None if we're just dealing with `PURPOSE` and lack an `ID`.
// In such cases, the whole thing is the purpose string.
let parts = remaining_text.split_once(' ');
let (purpose_str, agent_id_string_option) = if let Some(parts) = parts {
(parts.0, Some(parts.1.to_owned()))
} else {
(remaining_text, None)
};
let Some(purpose) = AgentPurpose::from_str(purpose_str) else {
return Err(ControllerType::Error(
strings::agent::purpose_unrecognized(purpose_str).to_owned(),
));
};
let agent_identifier = match agent_id_string_option {
Some(agent_id_string) => {
let Some(agent_identifier) = PublicIdentifier::from_str(&agent_id_string) else {
return Err(ControllerType::Error(
strings::agent::invalid_id_generic().to_owned(),
));
};
Some(agent_identifier)
}
None => None,
};
return Ok(ConfigSettingRelatedControllerType::SetHandler(
purpose,
agent_identifier,
));
}
if let Some(remaining_text) = text.strip_prefix("text-generation") {
return match text_generation::determine(remaining_text.trim()) {
Ok(handler) => Ok(ConfigSettingRelatedControllerType::TextGeneration(handler)),
Err(controller_type) => Err(controller_type),
};
}
if let Some(remaining_text) = text.strip_prefix("text-to-speech") {
return match text_to_speech::determine(remaining_text.trim()) {
Ok(handler) => Ok(ConfigSettingRelatedControllerType::TextToSpeech(handler)),
Err(controller_type) => Err(controller_type),
};
}
if let Some(remaining_text) = text.strip_prefix("speech-to-text") {
return match speech_to_text::determine(remaining_text.trim()) {
Ok(handler) => Ok(ConfigSettingRelatedControllerType::SpeechToText(handler)),
Err(controller_type) => Err(controller_type),
};
}
Err(ControllerType::Unknown)
}

View File

@@ -0,0 +1,87 @@
#[cfg(test)]
mod tests;
use crate::{controller::ControllerType, entity::roomconfig::SpeechToTextFlowType, strings};
use super::super::controller_type::ConfigSpeechToTextSettingRelatedControllerType;
pub(super) fn determine(
text: &str,
) -> Result<ConfigSpeechToTextSettingRelatedControllerType, ControllerType> {
// Flow Type
if let Some(remaining_text) = text.strip_prefix("flow-type") {
let remaining_text = remaining_text.trim();
if !remaining_text.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_getter_used_with_extra_text(
"flow-type",
remaining_text,
)
.to_owned(),
));
}
return Ok(ConfigSpeechToTextSettingRelatedControllerType::GetFlowType);
}
if let Some(value_string) = text.strip_prefix("set-flow-type") {
let value_string = value_string.trim().to_owned();
let value_choice = if value_string.is_empty() {
None
} else {
let value_choice = SpeechToTextFlowType::from_str(&value_string.to_lowercase());
if value_choice.is_none() {
return Err(ControllerType::Error(
strings::cfg::configuration_value_unrecognized(&value_string).to_owned(),
));
}
value_choice
};
return Ok(ConfigSpeechToTextSettingRelatedControllerType::SetFlowType(
value_choice,
));
}
// Language
if let Some(remaining_text) = text.strip_prefix("language") {
let remaining_text = remaining_text.trim();
if !remaining_text.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_getter_used_with_extra_text("language", remaining_text)
.to_owned(),
));
}
return Ok(ConfigSpeechToTextSettingRelatedControllerType::GetLanguage);
}
if let Some(value_string) = text.strip_prefix("set-language") {
let value_string = value_string.trim().to_owned();
let value_string = if value_string.is_empty() {
None
} else {
if value_string.len() != 2 {
return Err(ControllerType::Error(
strings::speech_to_text::language_code_invalid(&value_string).to_owned(),
));
}
Some(value_string)
};
return Ok(ConfigSpeechToTextSettingRelatedControllerType::SetLanguage(
value_string,
));
}
Err(ControllerType::Unknown)
}

View File

@@ -0,0 +1,136 @@
#[test]
fn determine_controller_other() {
use super::ConfigSpeechToTextSettingRelatedControllerType;
use super::ControllerType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigSpeechToTextSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![TestCase {
name: "Unknown",
input: "whatever",
expected: Err(ControllerType::Unknown),
}];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}
#[test]
fn determine_controller_flow_type() {
use super::ConfigSpeechToTextSettingRelatedControllerType;
use super::ControllerType;
use crate::entity::roomconfig::SpeechToTextFlowType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigSpeechToTextSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![
TestCase {
name: "flow-type getter ok",
input: "flow-type",
expected: Ok(ConfigSpeechToTextSettingRelatedControllerType::GetFlowType),
},
TestCase {
name: "flow-type getter extra args",
input: "flow-type some values here",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_getter_used_with_extra_text(
"flow-type",
"some values here",
),
)),
},
TestCase {
name: "flow-type setter",
input: "set-flow-type transcribe_and_generate_text",
expected: Ok(ConfigSpeechToTextSettingRelatedControllerType::SetFlowType(
Some(SpeechToTextFlowType::TranscribeAndGenerateText),
)),
},
TestCase {
name: "flow-type setter",
input: "set-flow-type unknown-Value",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_value_unrecognized("unknown-Value"),
)),
},
TestCase {
name: "flow-type unsetter",
input: "set-flow-type",
expected: Ok(ConfigSpeechToTextSettingRelatedControllerType::SetFlowType(
None,
)),
},
];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}
#[test]
fn determine_controller_language() {
use super::ConfigSpeechToTextSettingRelatedControllerType;
use super::ControllerType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigSpeechToTextSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![
TestCase {
name: "language getter ok",
input: "language",
expected: Ok(ConfigSpeechToTextSettingRelatedControllerType::GetLanguage),
},
TestCase {
name: "language getter extra args",
input: "language some values here",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_getter_used_with_extra_text(
"language",
"some values here",
),
)),
},
TestCase {
name: "language setter 2-letter code (ja)",
input: "set-language ja",
expected: Ok(ConfigSpeechToTextSettingRelatedControllerType::SetLanguage(
Some("ja".to_owned()),
)),
},
// OpenAI does not support 3-letter codes, so we won't be allowing it either
TestCase {
name: "language setter 3-letter code (jpn) fails",
input: "set-language jpn",
expected: Err(ControllerType::Error(
crate::strings::speech_to_text::language_code_invalid("jpn"),
)),
},
TestCase {
name: "language unsetter",
input: "set-language",
expected: Ok(ConfigSpeechToTextSettingRelatedControllerType::SetLanguage(
None,
)),
},
];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}

View File

@@ -0,0 +1,212 @@
#[test]
fn determine_controller() {
use super::super::controller_type;
use crate::agent::{AgentPurpose, PublicIdentifier};
struct TestCase {
name: &'static str,
input: &'static str,
expected: super::ControllerType,
}
let test_cases = vec![
TestCase {
name: "Top-level is help",
input: "",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::Help),
},
TestCase {
name: "unknown commands is help",
input: "whatever",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::Help),
},
TestCase {
name: "Status",
input: "status",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::Status),
},
TestCase {
name: "per-room handler getter - catch-all",
input: "room handler catch-all",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Room,
controller_type::ConfigSettingRelatedControllerType::GetHandler(AgentPurpose::CatchAll),
)),
},
TestCase {
name: "per-room handler getter - text-generation",
input: "room handler text-generation",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Room,
controller_type::ConfigSettingRelatedControllerType::GetHandler(AgentPurpose::TextGeneration),
)),
},
TestCase {
name: "per-room handler getter - invalid purpose",
input: "room handler invalid-purpose-here",
expected: super::ControllerType::Error(
crate::strings::agent::purpose_unrecognized("invalid-purpose-here").to_owned()
),
},
TestCase {
name: "per-room handler getter - invalid purpose with spaces",
input: "room handler invalid purpose here",
expected: super::ControllerType::Error(
crate::strings::agent::purpose_unrecognized("invalid purpose here").to_owned()
),
},
TestCase {
name: "per-room handler setter - too few values",
input: "room set-handler",
expected: super::ControllerType::Error(
crate::strings::cfg::configuration_invocation_incorrect_more_values_expected().to_owned()
),
},
TestCase {
name: "per-room handler setter - catch-all",
input: "room set-handler catch-all static/agent-id",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Room,
controller_type::ConfigSettingRelatedControllerType::SetHandler(AgentPurpose::CatchAll, Some(
PublicIdentifier::Static("agent-id".to_owned())
)),
)),
},
TestCase {
name: "per-room handler setter - catch-all with bare agent id",
input: "room set-handler catch-all agent-id",
expected: super::ControllerType::Error(
crate::strings::agent::invalid_id_generic().to_owned()
),
},
TestCase {
name: "per-room handler setter - catch-all unsetter",
input: "room set-handler catch-all",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Room,
controller_type::ConfigSettingRelatedControllerType::SetHandler(AgentPurpose::CatchAll, None),
)),
},
TestCase {
name: "per-room handler setter - text-generation",
input: "room set-handler text-generation room-local/agent-id",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Room,
controller_type::ConfigSettingRelatedControllerType::SetHandler(AgentPurpose::TextGeneration, Some(
PublicIdentifier::DynamicRoomLocal("agent-id".to_owned())
)),
)),
},
TestCase {
name: "per-room handler setter - too many values",
input: "room set-handler text-generation agent-id more values here",
expected: super::ControllerType::Error(
crate::strings::agent::invalid_id_generic().to_owned()
),
},
// We have few global handler test cases. We've exercised the per-room handlers enough.
// These share the same code path, so we don't need to test all the permutations again.
TestCase {
name: "global handler getter - catch-all",
input: "global handler catch-all",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Global,
controller_type::ConfigSettingRelatedControllerType::GetHandler(AgentPurpose::CatchAll),
)),
},
TestCase {
name: "global handler setter - text-generation with global agent",
input: "global set-handler text-generation global/agent-id",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Global,
controller_type::ConfigSettingRelatedControllerType::SetHandler(AgentPurpose::TextGeneration, Some(
PublicIdentifier::DynamicGlobal("agent-id".to_owned())
)),
)),
},
// This test case passes, even though the handler function will subsequently reject using room-local agents for global handlers.
TestCase {
name: "global handler setter - text-generation with room-local agent",
input: "global set-handler text-generation room-local/agent-id",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Global,
controller_type::ConfigSettingRelatedControllerType::SetHandler(AgentPurpose::TextGeneration, Some(
PublicIdentifier::DynamicRoomLocal("agent-id".to_owned())
)),
)),
},
// We'll only test one handler per sub-category to ensure proper routing is done here.
// Extensive tests for each sub-category are done in their respective modules.
TestCase {
name: "per-room text-generation/context-management-enabled getter",
input: "room text-generation context-management-enabled",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Room,
controller_type::ConfigSettingRelatedControllerType::TextGeneration(
controller_type::ConfigTextGenerationSettingRelatedControllerType::GetContextManagementEnabled,
),
)),
},
TestCase {
name: "global text-generation/context-management-enabled getter",
input: "global text-generation context-management-enabled",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Global,
controller_type::ConfigSettingRelatedControllerType::TextGeneration(
controller_type::ConfigTextGenerationSettingRelatedControllerType::GetContextManagementEnabled,
),
)),
},
TestCase {
name: "per-room text-to-speech/speed-override getter",
input: "room text-to-speech speed-override",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Room,
controller_type::ConfigSettingRelatedControllerType::TextToSpeech(
controller_type::ConfigTextToSpeechSettingRelatedControllerType::GetSpeedOverride,
),
)),
},
TestCase {
name: "global text-to-speech/speed-override getter",
input: "global text-to-speech speed-override",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Global,
controller_type::ConfigSettingRelatedControllerType::TextToSpeech(
controller_type::ConfigTextToSpeechSettingRelatedControllerType::GetSpeedOverride,
),
)),
},
TestCase {
name: "room speech-to-text/flow-type getter",
input: "room speech-to-text flow-type",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Room,
controller_type::ConfigSettingRelatedControllerType::SpeechToText(
controller_type::ConfigSpeechToTextSettingRelatedControllerType::GetFlowType,
),
)),
},
TestCase {
name: "global speech-to-text/flow-type getter",
input: "global speech-to-text flow-type",
expected: super::ControllerType::Config(controller_type::ConfigControllerType::SettingsRelated(
controller_type::SettingsStorageSource::Global,
controller_type::ConfigSettingRelatedControllerType::SpeechToText(
controller_type::ConfigSpeechToTextSettingRelatedControllerType::GetFlowType,
),
)),
},
];
for test_case in test_cases {
let result = super::determine_controller(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}

View File

@@ -0,0 +1,201 @@
#[cfg(test)]
mod tests;
use crate::{
controller::ControllerType,
entity::roomconfig::{TextGenerationAutoUsage, TextGenerationPrefixRequirementType},
strings,
};
use super::super::controller_type::ConfigTextGenerationSettingRelatedControllerType;
pub(super) fn determine(
text: &str,
) -> Result<ConfigTextGenerationSettingRelatedControllerType, ControllerType> {
if let Some(remaining_text) = text.strip_prefix("context-management-enabled") {
let remaining_text = remaining_text.trim();
if !remaining_text.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_getter_used_with_extra_text(
"context-management-enabled",
remaining_text,
)
.to_owned(),
));
}
return Ok(ConfigTextGenerationSettingRelatedControllerType::GetContextManagementEnabled);
}
if let Some(value_string) = text.strip_prefix("set-context-management-enabled") {
let value_string = value_string.trim().to_owned();
let value_opt = if value_string.is_empty() {
None
} else {
let value_string_lowercase = value_string.to_lowercase();
Some(match value_string_lowercase.as_str() {
"true" => true,
"false" => false,
_ => {
return Err(ControllerType::Error(
strings::cfg::configuration_value_unrecognized(&value_string).to_owned(),
));
}
})
};
return Ok(
ConfigTextGenerationSettingRelatedControllerType::SetContextManagementEnabled(
value_opt,
),
);
}
if let Some(remaining_text) = text.strip_prefix("prefix-requirement-type") {
let remaining_text = remaining_text.trim();
if !remaining_text.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_getter_used_with_extra_text(
"prefix-requirement-type",
remaining_text,
)
.to_owned(),
));
}
return Ok(ConfigTextGenerationSettingRelatedControllerType::GetPrefixRequirementType);
}
if let Some(value_string) = text.strip_prefix("set-prefix-requirement-type") {
let value_string = value_string.trim().to_owned();
let value_choice = if value_string.is_empty() {
None
} else {
let value_choice =
TextGenerationPrefixRequirementType::from_str(&value_string.to_lowercase());
if value_choice.is_none() {
return Err(ControllerType::Error(
strings::cfg::configuration_value_unrecognized(&value_string).to_owned(),
));
}
value_choice
};
return Ok(
ConfigTextGenerationSettingRelatedControllerType::SetPrefixRequirementType(
value_choice,
),
);
}
if let Some(remaining_text) = text.strip_prefix("auto-usage") {
let remaining_text = remaining_text.trim();
if !remaining_text.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_getter_used_with_extra_text(
"auto-usage",
remaining_text,
)
.to_owned(),
));
}
return Ok(ConfigTextGenerationSettingRelatedControllerType::GetAutoUsage);
}
if let Some(value_string) = text.strip_prefix("set-auto-usage") {
let value_string = value_string.trim().to_owned();
let value_choice = if value_string.is_empty() {
None
} else {
let value_choice = TextGenerationAutoUsage::from_str(&value_string.to_lowercase());
if value_choice.is_none() {
return Err(ControllerType::Error(
strings::cfg::configuration_value_unrecognized(&value_string).to_owned(),
));
}
value_choice
};
return Ok(ConfigTextGenerationSettingRelatedControllerType::SetAutoUsage(value_choice));
}
if let Some(remaining_text) = text.strip_prefix("prompt-override") {
let remaining_text = remaining_text.trim();
if !remaining_text.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_getter_used_with_extra_text(
"prompt-override",
remaining_text,
)
.to_owned(),
));
}
return Ok(ConfigTextGenerationSettingRelatedControllerType::GetPromptOverride);
}
if let Some(value_string) = text.strip_prefix("set-prompt-override") {
let value_string = value_string.trim().to_owned();
if value_string.is_empty() {
return Ok(ConfigTextGenerationSettingRelatedControllerType::SetPromptOverride(None));
}
return Ok(
ConfigTextGenerationSettingRelatedControllerType::SetPromptOverride(Some(value_string)),
);
}
if let Some(remaining_text) = text.strip_prefix("temperature-override") {
let remaining_text = remaining_text.trim();
if !remaining_text.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_getter_used_with_extra_text(
"temperature-override",
remaining_text,
)
.to_owned(),
));
}
return Ok(ConfigTextGenerationSettingRelatedControllerType::GetTemperatureOverride);
}
if let Some(value_string) = text.strip_prefix("set-temperature-override") {
let value_string = value_string.trim().to_owned();
if value_string.is_empty() {
return Ok(
ConfigTextGenerationSettingRelatedControllerType::SetTemperatureOverride(None),
);
}
let value_f32 = value_string.parse::<f32>();
let Ok(value_f32) = value_f32 else {
return Err(ControllerType::Error(
strings::cfg::configuration_value_not_f32(&value_string).to_owned(),
));
};
return Ok(
ConfigTextGenerationSettingRelatedControllerType::SetTemperatureOverride(Some(
value_f32,
)),
);
}
Err(ControllerType::Unknown)
}

View File

@@ -0,0 +1,332 @@
#[test]
fn determine_controller_other() {
use super::ConfigTextGenerationSettingRelatedControllerType;
use super::ControllerType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigTextGenerationSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![TestCase {
name: "Unknown",
input: "whatever",
expected: Err(ControllerType::Unknown),
}];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}
#[test]
fn determine_controller_context_management() {
use super::ConfigTextGenerationSettingRelatedControllerType;
use super::ControllerType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigTextGenerationSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![
TestCase {
name: "context-management-enabled getter ok",
input: "context-management-enabled",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::GetContextManagementEnabled,
),
},
TestCase {
name: "context-management-enabled getter extra args",
input: "context-management-enabled some values here",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_getter_used_with_extra_text(
"context-management-enabled",
"some values here",
),
)),
},
TestCase {
name: "context-management-enabled setter",
input: "set-context-management-enabled true",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::SetContextManagementEnabled(
Some(true),
),
),
},
TestCase {
name: "context-management-enabled setter uppercase",
input: "set-context-management-enabled TRUE",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::SetContextManagementEnabled(
Some(true),
),
),
},
TestCase {
name: "context-management-enabled setter non-bool",
input: "set-context-management-enabled non-Bool-Value",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_value_unrecognized("non-Bool-Value"),
)),
},
TestCase {
name: "context-management-enabled unsetter",
input: "set-context-management-enabled",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::SetContextManagementEnabled(None),
),
},
];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}
#[test]
fn determine_controller_prefix_requirement_type() {
use super::ConfigTextGenerationSettingRelatedControllerType;
use super::ControllerType;
use crate::entity::roomconfig::TextGenerationPrefixRequirementType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigTextGenerationSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![
TestCase {
name: "prefix-requirement-type getter ok",
input: "prefix-requirement-type",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::GetPrefixRequirementType,
),
},
TestCase {
name: "prefix-requirement-type getter extra args",
input: "prefix-requirement-type some values here",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_getter_used_with_extra_text(
"prefix-requirement-type",
"some values here",
),
)),
},
TestCase {
name: "prefix-requirement-type setter (command_prefix)",
input: "set-prefix-requirement-type command_prefix",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::SetPrefixRequirementType(Some(
TextGenerationPrefixRequirementType::CommandPrefix,
)),
),
},
TestCase {
name: "prefix-requirement-type setter (no)",
input: "set-prefix-requirement-type no",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::SetPrefixRequirementType(Some(
TextGenerationPrefixRequirementType::No,
)),
),
},
TestCase {
name: "prefix-requirement-type setter",
input: "set-prefix-requirement-type unknown-Value",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_value_unrecognized("unknown-Value"),
)),
},
TestCase {
name: "prefix-requirement-type unsetter",
input: "set-prefix-requirement-type",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::SetPrefixRequirementType(None),
),
},
];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}
#[test]
fn determine_controller_auto_usage() {
use super::ConfigTextGenerationSettingRelatedControllerType;
use super::ControllerType;
use crate::entity::roomconfig::TextGenerationAutoUsage;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigTextGenerationSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![
TestCase {
name: "auto-usage getter ok",
input: "auto-usage",
expected: Ok(ConfigTextGenerationSettingRelatedControllerType::GetAutoUsage),
},
TestCase {
name: "auto-usage getter extra args",
input: "auto-usage some values here",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_getter_used_with_extra_text(
"auto-usage",
"some values here",
),
)),
},
TestCase {
name: "auto-usage setter",
input: "set-auto-usage only_for_voice",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::SetAutoUsage(Some(
TextGenerationAutoUsage::OnlyForVoice,
)),
),
},
TestCase {
name: "auto-usage setter",
input: "set-auto-usage unknown-Value",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_value_unrecognized("unknown-Value"),
)),
},
TestCase {
name: "auto-usage unsetter",
input: "set-auto-usage",
expected: Ok(ConfigTextGenerationSettingRelatedControllerType::SetAutoUsage(None)),
},
];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}
#[test]
fn determine_controller_prompt_override() {
use super::ConfigTextGenerationSettingRelatedControllerType;
use super::ControllerType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigTextGenerationSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![
TestCase {
name: "prompt-override getter ok",
input: "prompt-override",
expected: Ok(ConfigTextGenerationSettingRelatedControllerType::GetPromptOverride),
},
TestCase {
name: "prompt-override getter extra args",
input: "prompt-override some values here",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_getter_used_with_extra_text(
"prompt-override",
"some values here",
),
)),
},
TestCase {
name: "prompt-override setter with multiple words",
input: "set-prompt-override Hello! You are a bot",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::SetPromptOverride(Some(
"Hello! You are a bot".to_owned(),
)),
),
},
TestCase {
name: "prompt-override setter with multi-line",
input: "set-prompt-override Hello!\n\nYou are a bot",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::SetPromptOverride(Some(
"Hello!\n\nYou are a bot".to_owned(),
)),
),
},
TestCase {
name: "prompt-override unsetter",
input: "set-prompt-override",
expected: Ok(ConfigTextGenerationSettingRelatedControllerType::SetPromptOverride(None)),
},
];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}
#[test]
fn determine_controller_temperature_override() {
use super::ConfigTextGenerationSettingRelatedControllerType;
use super::ControllerType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigTextGenerationSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![
TestCase {
name: "temperature-override getter ok",
input: "temperature-override",
expected: Ok(ConfigTextGenerationSettingRelatedControllerType::GetTemperatureOverride),
},
TestCase {
name: "temperature-override getter extra args",
input: "temperature-override some values here",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_getter_used_with_extra_text(
"temperature-override",
"some values here",
),
)),
},
TestCase {
name: "temperature-override setter",
input: "set-temperature-override 0.5",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::SetTemperatureOverride(Some(0.5)),
),
},
TestCase {
name: "temperature-override setter",
input: "set-temperature-override unknown-Value",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_value_not_f32("unknown-Value"),
)),
},
TestCase {
name: "temperature-override unsetter",
input: "set-temperature-override",
expected: Ok(
ConfigTextGenerationSettingRelatedControllerType::SetTemperatureOverride(None),
),
},
];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}

View File

@@ -0,0 +1,158 @@
#[cfg(test)]
mod tests;
use crate::{
controller::ControllerType,
entity::roomconfig::{TextToSpeechBotMessagesFlowType, TextToSpeechUserMessagesFlowType},
strings,
};
use super::super::controller_type::ConfigTextToSpeechSettingRelatedControllerType;
pub(super) fn determine(
text: &str,
) -> Result<ConfigTextToSpeechSettingRelatedControllerType, ControllerType> {
if let Some(remaining_text) = text.strip_prefix("bot-msgs-flow-type") {
let remaining_text = remaining_text.trim();
if !remaining_text.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_getter_used_with_extra_text(
"bot-msgs-flow-type",
remaining_text,
)
.to_owned(),
));
}
return Ok(ConfigTextToSpeechSettingRelatedControllerType::GetBotMessagesFlowType);
}
if let Some(value_string) = text.strip_prefix("set-bot-msgs-flow-type") {
let value_string = value_string.trim().to_owned();
let value_choice = if value_string.is_empty() {
None
} else {
let value_choice =
TextToSpeechBotMessagesFlowType::from_str(&value_string.to_lowercase());
if value_choice.is_none() {
return Err(ControllerType::Error(
strings::cfg::configuration_value_unrecognized(&value_string).to_owned(),
));
}
value_choice
};
return Ok(
ConfigTextToSpeechSettingRelatedControllerType::SetBotMessagesFlowType(value_choice),
);
}
if let Some(remaining_text) = text.strip_prefix("user-msgs-flow-type") {
let remaining_text = remaining_text.trim();
if !remaining_text.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_getter_used_with_extra_text(
"user-msgs-flow-type",
remaining_text,
)
.to_owned(),
));
}
return Ok(ConfigTextToSpeechSettingRelatedControllerType::GetUserMessagesFlowType);
}
if let Some(value_string) = text.strip_prefix("set-user-msgs-flow-type") {
let value_string = value_string.trim().to_owned();
let value_choice = if value_string.is_empty() {
None
} else {
let value_choice =
TextToSpeechUserMessagesFlowType::from_str(&value_string.to_lowercase());
if value_choice.is_none() {
return Err(ControllerType::Error(
strings::cfg::configuration_value_unrecognized(&value_string).to_owned(),
));
}
value_choice
};
return Ok(
ConfigTextToSpeechSettingRelatedControllerType::SetUserMessagesFlowType(value_choice),
);
}
if let Some(remaining_text) = text.strip_prefix("speed-override") {
let remaining_text = remaining_text.trim();
if !remaining_text.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_getter_used_with_extra_text(
"speed-override",
remaining_text,
)
.to_owned(),
));
}
return Ok(ConfigTextToSpeechSettingRelatedControllerType::GetSpeedOverride);
}
if let Some(value_string) = text.strip_prefix("set-speed-override") {
let value_string = value_string.trim().to_owned();
if value_string.is_empty() {
return Ok(ConfigTextToSpeechSettingRelatedControllerType::SetSpeedOverride(None));
}
let value_f32 = value_string.parse::<f32>();
let Ok(value_f32) = value_f32 else {
return Err(ControllerType::Error(
strings::cfg::configuration_value_not_f32(&value_string).to_owned(),
));
};
return Ok(
ConfigTextToSpeechSettingRelatedControllerType::SetSpeedOverride(Some(value_f32)),
);
}
if let Some(remaining_text) = text.strip_prefix("voice-override") {
let remaining_text = remaining_text.trim();
if !remaining_text.is_empty() {
return Err(ControllerType::Error(
strings::cfg::configuration_getter_used_with_extra_text(
"voice-override",
remaining_text,
)
.to_owned(),
));
}
return Ok(ConfigTextToSpeechSettingRelatedControllerType::GetVoiceOverride);
}
if let Some(value_string) = text.strip_prefix("set-voice-override") {
let value_string = value_string.trim().to_owned();
if value_string.is_empty() {
return Ok(ConfigTextToSpeechSettingRelatedControllerType::SetVoiceOverride(None));
}
return Ok(
ConfigTextToSpeechSettingRelatedControllerType::SetVoiceOverride(Some(value_string)),
);
}
Err(ControllerType::Unknown)
}

View File

@@ -0,0 +1,252 @@
#[test]
fn determine_controller_other() {
use super::ConfigTextToSpeechSettingRelatedControllerType;
use super::ControllerType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigTextToSpeechSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![TestCase {
name: "Unknown",
input: "whatever",
expected: Err(ControllerType::Unknown),
}];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}
#[test]
fn determine_controller_bot_msgs_flow_type() {
use super::ConfigTextToSpeechSettingRelatedControllerType;
use super::ControllerType;
use crate::entity::roomconfig::TextToSpeechBotMessagesFlowType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigTextToSpeechSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![
TestCase {
name: "bot-msgs-flow-type getter ok",
input: "bot-msgs-flow-type",
expected: Ok(ConfigTextToSpeechSettingRelatedControllerType::GetBotMessagesFlowType),
},
TestCase {
name: "bot-msgs-flow-type getter extra args",
input: "bot-msgs-flow-type some values here",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_getter_used_with_extra_text(
"bot-msgs-flow-type",
"some values here",
),
)),
},
TestCase {
name: "bot-msgs-flow-type setter",
input: "set-bot-msgs-flow-type only_for_voice",
expected: Ok(
ConfigTextToSpeechSettingRelatedControllerType::SetBotMessagesFlowType(Some(
TextToSpeechBotMessagesFlowType::OnlyForVoice,
)),
),
},
TestCase {
name: "bot-msgs-flow-type setter",
input: "set-bot-msgs-flow-type unknown-Value",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_value_unrecognized("unknown-Value"),
)),
},
TestCase {
name: "bot-msgs-flow-type unsetter",
input: "set-bot-msgs-flow-type",
expected: Ok(
ConfigTextToSpeechSettingRelatedControllerType::SetBotMessagesFlowType(None),
),
},
];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}
#[test]
fn determine_controller_user_msgs_flow_type() {
use super::ConfigTextToSpeechSettingRelatedControllerType;
use super::ControllerType;
use crate::entity::roomconfig::TextToSpeechUserMessagesFlowType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigTextToSpeechSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![
TestCase {
name: "user-msgs-flow-type getter ok",
input: "user-msgs-flow-type",
expected: Ok(ConfigTextToSpeechSettingRelatedControllerType::GetUserMessagesFlowType),
},
TestCase {
name: "user-msgs-flow-type getter extra args",
input: "user-msgs-flow-type some values here",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_getter_used_with_extra_text(
"user-msgs-flow-type",
"some values here",
),
)),
},
TestCase {
name: "user-msgs-flow-type setter",
input: "set-user-msgs-flow-type on_demand",
expected: Ok(
ConfigTextToSpeechSettingRelatedControllerType::SetUserMessagesFlowType(Some(
TextToSpeechUserMessagesFlowType::OnDemand,
)),
),
},
TestCase {
name: "user-msgs-flow-type setter",
input: "set-user-msgs-flow-type unknown-Value",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_value_unrecognized("unknown-Value"),
)),
},
TestCase {
name: "user-msgs-flow-type unsetter",
input: "set-user-msgs-flow-type",
expected: Ok(
ConfigTextToSpeechSettingRelatedControllerType::SetUserMessagesFlowType(None),
),
},
];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}
#[test]
fn determine_controller_speed_override() {
use super::ConfigTextToSpeechSettingRelatedControllerType;
use super::ControllerType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigTextToSpeechSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![
TestCase {
name: "speed-override getter ok",
input: "speed-override",
expected: Ok(ConfigTextToSpeechSettingRelatedControllerType::GetSpeedOverride),
},
TestCase {
name: "speed-override getter extra args",
input: "speed-override some values here",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_getter_used_with_extra_text(
"speed-override",
"some values here",
),
)),
},
TestCase {
name: "speed-override setter",
input: "set-speed-override 0.5",
expected: Ok(
ConfigTextToSpeechSettingRelatedControllerType::SetSpeedOverride(Some(0.5)),
),
},
TestCase {
name: "speed-override setter",
input: "set-speed-override unknown-Value",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_value_not_f32("unknown-Value"),
)),
},
TestCase {
name: "speed-override unsetter",
input: "set-speed-override",
expected: Ok(ConfigTextToSpeechSettingRelatedControllerType::SetSpeedOverride(None)),
},
];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}
#[test]
fn determine_controller_voice_override() {
use super::ConfigTextToSpeechSettingRelatedControllerType;
use super::ControllerType;
struct TestCase {
name: &'static str,
input: &'static str,
expected: Result<ConfigTextToSpeechSettingRelatedControllerType, ControllerType>,
}
let test_cases = vec![
TestCase {
name: "voice-override getter ok",
input: "voice-override",
expected: Ok(ConfigTextToSpeechSettingRelatedControllerType::GetVoiceOverride),
},
TestCase {
name: "voice-override getter extra args",
input: "voice-override some values here",
expected: Err(ControllerType::Error(
crate::strings::cfg::configuration_getter_used_with_extra_text(
"voice-override",
"some values here",
),
)),
},
TestCase {
name: "voice-override setter",
input: "set-voice-override alex",
expected: Ok(
ConfigTextToSpeechSettingRelatedControllerType::SetVoiceOverride(Some(
"alex".to_owned(),
)),
),
},
TestCase {
name: "voice-override setter preserves case",
input: "set-voice-override Alex",
expected: Ok(
ConfigTextToSpeechSettingRelatedControllerType::SetVoiceOverride(Some(
"Alex".to_owned(),
)),
),
},
TestCase {
name: "voice-override unsetter",
input: "set-voice-override",
expected: Ok(ConfigTextToSpeechSettingRelatedControllerType::SetVoiceOverride(None)),
},
];
for test_case in test_cases {
let result = super::determine(test_case.input);
assert_eq!(result, test_case.expected, "Test case: {}", test_case.name);
}
}