Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/adaptive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ redis-backend = ["redis"]
__skip-implicit-config = ["nemo-relay/__skip-implicit-config"]

[dev-dependencies]
nemo-relay = { workspace = true, features = ["__test-plugin-host"] }
tokio = { version = "1", default-features = false, features = ["rt", "macros", "sync", "time", "test-util", "rt-multi-thread"] }

[[test]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use nemo_relay::api::event::Event;
use nemo_relay::api::llm::LlmRequest;
use nemo_relay::api::runtime::{LlmExecutionNextFn, NemoRelayContextState, global_context};
use nemo_relay::api::subscriber::{deregister_subscriber, flush_subscribers, register_subscriber};
use nemo_relay::plugin::clear_plugin_configuration;
use nemo_relay::plugin::test_close_plugin_host;
use nemo_relay_adaptive::ResponseCacheConfig;
use serde_json::{Value as Json, json};
use tokio::sync::Mutex;
Expand All @@ -42,7 +42,7 @@ static TEST_MUTEX: Mutex<()> = Mutex::const_new(());
const PER_CALL_TOTAL_TOKENS: u64 = 1280;

fn reset_global() {
let _ = clear_plugin_configuration();
let _ = test_close_plugin_host();
let ctx = global_context();
let mut state = ctx.write().unwrap();
*state = NemoRelayContextState::new();
Expand Down Expand Up @@ -286,7 +286,7 @@ async fn reinitialized_cache_starts_empty() {

// Runs one repeat workload against a fresh cache and returns the observed
// hit count. Each invocation resets the global state and re-activates the
// cache, so `initialize_plugins_exact` builds a brand-new in-memory store.
// cache, so `test_initialize_plugin_host_exact` builds a brand-new in-memory store.
async fn run_once(subscriber: &str) -> usize {
reset_global();
activate_cache(bench_config()).await;
Expand Down
4 changes: 2 additions & 2 deletions crates/adaptive/tests/integration/response_cache_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

use nemo_relay::api::llm::{LlmCallExecuteParams, LlmRequest, llm_call_execute};
use nemo_relay::api::runtime::LlmExecutionNextFn;
use nemo_relay::plugin::{PluginConfig, initialize_plugins_exact};
use nemo_relay::plugin::{PluginConfig, test_initialize_plugin_host_exact};
use nemo_relay_adaptive::plugin_component::{ComponentSpec, register_adaptive_component};
use nemo_relay_adaptive::{AdaptiveConfig, ResponseCacheConfig};
use serde_json::{Value as Json, json};
Expand All @@ -31,7 +31,7 @@ pub async fn activate_cache(config: ResponseCacheConfig) {
response_cache: Some(config),
..AdaptiveConfig::default()
};
let report = initialize_plugins_exact(PluginConfig {
let report = test_initialize_plugin_host_exact(PluginConfig {
components: vec![ComponentSpec::new(adaptive).into()],
..PluginConfig::default()
})
Expand Down
30 changes: 15 additions & 15 deletions crates/adaptive/tests/integration/response_cache_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ use nemo_relay::api::subscriber::{deregister_subscriber, flush_subscribers, regi
use nemo_relay::api::tool::{ToolCallExecuteParams, tool_call_execute};
use nemo_relay::error::FlowError;
use nemo_relay::plugin::{
DiagnosticLevel, PluginConfig, clear_plugin_configuration, initialize_plugins_exact,
validate_plugin_config,
DiagnosticLevel, PluginConfig, test_close_plugin_host, test_initialize_plugin_host_exact,
test_validate_static_plugin_config,
};
use nemo_relay_adaptive::plugin_component::{ComponentSpec, register_adaptive_component};
use nemo_relay_adaptive::{
Expand All @@ -48,7 +48,7 @@ static TEST_MUTEX: Mutex<()> = Mutex::const_new(());
const ROUTING_BACKEND_HEADER: &str = "x-nemo-relay-internal-dispatch-backend";

fn reset_global() {
let _ = clear_plugin_configuration();
let _ = test_close_plugin_host();
let ctx = global_context();
let mut state = ctx.write().unwrap();
*state = NemoRelayContextState::new();
Expand Down Expand Up @@ -561,7 +561,7 @@ async fn invalid_config_is_rejected_by_validation() {
}),
..AdaptiveConfig::default()
};
let report = validate_plugin_config(&PluginConfig {
let report = test_validate_static_plugin_config(&PluginConfig {
components: vec![ComponentSpec::new(adaptive).into()],
..PluginConfig::default()
});
Expand Down Expand Up @@ -601,7 +601,7 @@ async fn unknown_and_unavailable_backends_are_rejected_by_validation() {
..ResponseCacheConfig::default()
};
config.backend.kind = kind.to_string();
validate_plugin_config(&PluginConfig {
test_validate_static_plugin_config(&PluginConfig {
components: vec![
ComponentSpec::new(AdaptiveConfig {
response_cache: Some(config),
Expand Down Expand Up @@ -660,7 +660,7 @@ async fn response_cache_validation_diagnostics_identify_the_invalid_setting() {
};
cache.backend.kind = "redis".to_string();

let report = validate_plugin_config(&PluginConfig {
let report = test_validate_static_plugin_config(&PluginConfig {
components: vec![
ComponentSpec::new(AdaptiveConfig {
response_cache: Some(cache),
Expand Down Expand Up @@ -1601,7 +1601,7 @@ async fn unsafe_cache_scope_headers_and_backends_are_rejected_by_validation() {
response_cache: Some(config),
..AdaptiveConfig::default()
};
validate_plugin_config(&PluginConfig {
test_validate_static_plugin_config(&PluginConfig {
components: vec![ComponentSpec::new(adaptive).into()],
..PluginConfig::default()
})
Expand Down Expand Up @@ -1877,7 +1877,7 @@ async fn cache_coexists_with_acg_execution_intercept() {
}),
..AdaptiveConfig::default()
};
let report = initialize_plugins_exact(PluginConfig {
let report = test_initialize_plugin_host_exact(PluginConfig {
components: vec![ComponentSpec::new(adaptive).into()],
..PluginConfig::default()
})
Expand Down Expand Up @@ -2466,7 +2466,7 @@ async fn invalid_tool_config_is_rejected_by_validation() {
})),
..AdaptiveConfig::default()
};
let report = validate_plugin_config(&PluginConfig {
let report = test_validate_static_plugin_config(&PluginConfig {
components: vec![ComponentSpec::new(adaptive).into()],
..PluginConfig::default()
});
Expand Down Expand Up @@ -2528,7 +2528,7 @@ async fn wildcard_member_validation_rules() {
})),
..AdaptiveConfig::default()
};
validate_plugin_config(&PluginConfig {
test_validate_static_plugin_config(&PluginConfig {
components: vec![ComponentSpec::new(adaptive).into()],
..PluginConfig::default()
})
Expand Down Expand Up @@ -2642,7 +2642,7 @@ async fn wildcard_member_validation_rules() {
})),
..AdaptiveConfig::default()
};
let report = validate_plugin_config(&PluginConfig {
let report = test_validate_static_plugin_config(&PluginConfig {
components: vec![ComponentSpec::new(adaptive).into()],
..PluginConfig::default()
});
Expand Down Expand Up @@ -2671,7 +2671,7 @@ async fn wildcard_member_validation_rules() {
})),
..AdaptiveConfig::default()
};
let report = validate_plugin_config(&PluginConfig {
let report = test_validate_static_plugin_config(&PluginConfig {
components: vec![ComponentSpec::new(adaptive).into()],
..PluginConfig::default()
});
Expand Down Expand Up @@ -2707,7 +2707,7 @@ async fn wildcard_member_validation_rules() {
})),
..AdaptiveConfig::default()
};
let report = validate_plugin_config(&PluginConfig {
let report = test_validate_static_plugin_config(&PluginConfig {
components: vec![ComponentSpec::new(adaptive).into()],
..PluginConfig::default()
});
Expand Down Expand Up @@ -2747,7 +2747,7 @@ async fn wildcard_member_validation_rules() {
})),
..AdaptiveConfig::default()
};
let report = validate_plugin_config(&PluginConfig {
let report = test_validate_static_plugin_config(&PluginConfig {
components: vec![ComponentSpec::new(adaptive).into()],
..PluginConfig::default()
});
Expand Down Expand Up @@ -2788,7 +2788,7 @@ async fn unknown_tool_field_warns_but_valid_class_names_do_not() {
enabled: true,
config: adaptive_json.as_object().unwrap().clone(),
};
let report = validate_plugin_config(&PluginConfig {
let report = test_validate_static_plugin_config(&PluginConfig {
components: vec![component],
..PluginConfig::default()
});
Expand Down
20 changes: 10 additions & 10 deletions crates/adaptive/tests/integration/runtime_integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ use nemo_relay::codec::traits::LlmResponseCodec;
use nemo_relay::error::{FlowError, Result as FlowResult};
use nemo_relay::plugin::{
ConfigDiagnostic, DiagnosticLevel, Plugin, PluginComponentSpec, PluginConfig, PluginError,
PluginRegistrationContext, clear_plugin_configuration, deregister_plugin,
initialize_plugins_exact, register_plugin, validate_plugin_config,
PluginRegistrationContext, deregister_plugin, register_plugin, test_close_plugin_host,
test_initialize_plugin_host_exact, test_validate_static_plugin_config,
};
use nemo_relay::plugin::{ConfigPolicy, UnsupportedBehavior};
use nemo_relay_adaptive::acg::{StabilityThresholds, analyze_stability, build_prompt_ir};
Expand Down Expand Up @@ -63,7 +63,7 @@ fn enable_operational_logs() {

fn reset_global() {
enable_operational_logs();
let _ = clear_plugin_configuration();
let _ = test_close_plugin_host();
let _ = deregister_plugin("test.header_plugin");
let _ = deregister_plugin("test.failing_plugin");

Expand Down Expand Up @@ -568,7 +568,7 @@ async fn test_adaptive_plugin_registers_and_passes_calls_through() {
reset_global();
register_adaptive_component().unwrap();

let report = initialize_plugins_exact(PluginConfig {
let report = test_initialize_plugin_host_exact(PluginConfig {
components: vec![
AdaptiveComponent::new(AdaptiveConfig {
state: Some(StateConfig {
Expand Down Expand Up @@ -630,14 +630,14 @@ async fn test_adaptive_plugin_registers_and_passes_calls_through() {
.unwrap();
assert_eq!(tool_result.result, json!({"query": "test"}));

clear_plugin_configuration().unwrap();
test_close_plugin_host().unwrap();
}

#[test]
fn test_adaptive_plugin_validation_reports_missing_state_and_unknown_fields() {
register_adaptive_component().unwrap();

let report = validate_plugin_config(&PluginConfig {
let report = test_validate_static_plugin_config(&PluginConfig {
components: vec![PluginComponentSpec {
kind: "adaptive".into(),
enabled: true,
Expand Down Expand Up @@ -676,7 +676,7 @@ async fn test_adaptive_plugin_rejects_unsupported_mode_with_strict_policy() {
reset_global();
register_adaptive_component().unwrap();

let err = initialize_plugins_exact(PluginConfig {
let err = test_initialize_plugin_host_exact(PluginConfig {
components: vec![
AdaptiveComponent::new(AdaptiveConfig {
policy: ConfigPolicy {
Expand Down Expand Up @@ -793,7 +793,7 @@ async fn test_top_level_plugin_registers_request_and_execution_intercepts() {
register_adaptive_component().unwrap();
register_plugin(Arc::new(HeaderPlugin)).unwrap();

initialize_plugins_exact(PluginConfig {
test_initialize_plugin_host_exact(PluginConfig {
components: vec![
AdaptiveComponent::new(AdaptiveConfig {
adaptive_hints: Some(AdaptiveHintsComponentConfig::default()),
Expand Down Expand Up @@ -884,7 +884,7 @@ async fn test_top_level_plugin_registers_request_and_execution_intercepts() {
json!(true)
);

clear_plugin_configuration().unwrap();
test_close_plugin_host().unwrap();
assert!(deregister_plugin("test.header_plugin"));
}

Expand Down Expand Up @@ -927,7 +927,7 @@ async fn test_top_level_plugin_registration_rolls_back_partial_work() {

register_plugin(Arc::new(FailingPlugin)).unwrap();

let err = initialize_plugins_exact(PluginConfig {
let err = test_initialize_plugin_host_exact(PluginConfig {
components: vec![PluginComponentSpec {
kind: "test.failing_plugin".into(),
enabled: true,
Expand Down
6 changes: 3 additions & 3 deletions crates/adaptive/tests/unit/plugin_component_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ use nemo_relay::api::llm::LlmRequest;
use nemo_relay::api::llm::llm_request_intercepts;
use nemo_relay::api::runtime::NemoRelayContextState;
use nemo_relay::api::runtime::global_context;
use nemo_relay::plugin::{DiagnosticLevel, UnsupportedBehavior, clear_plugin_configuration};
use nemo_relay::plugin::{DiagnosticLevel, UnsupportedBehavior, test_close_plugin_host};
use nemo_relay::plugin::{Plugin, PluginRegistrationContext, rollback_registrations};
use serde_json::json;
fn reset_global() {
let _ = clear_plugin_configuration();
let _ = test_close_plugin_host();
let _ = deregister_adaptive_component();
let ctx = global_context();
let mut state = ctx.write().unwrap();
Expand Down Expand Up @@ -81,7 +81,7 @@ fn validate_adaptive_plugin_config_reports_unknown_fields_and_backend_errors() {
#[tokio::test(flavor = "current_thread")]
async fn register_adaptive_component_is_idempotent_and_deregisters_cleanly() {
let _guard = crate::TEST_GLOBAL_CONTEXT_MUTEX.lock().await;
let _ = clear_plugin_configuration();
let _ = test_close_plugin_host();
let _ = deregister_adaptive_component();

register_adaptive_component().unwrap();
Expand Down
4 changes: 2 additions & 2 deletions crates/adaptive/tests/unit/runtime_features_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ use nemo_relay::api::subscriber::{deregister_subscriber, register_subscriber};
use nemo_relay::api::tool::tool_call_execute;
use nemo_relay::error::FlowError;
use nemo_relay::plugin::{ConfigPolicy, DiagnosticLevel, UnsupportedBehavior};
use nemo_relay::plugin::{clear_plugin_configuration, rollback_registrations};
use nemo_relay::plugin::{rollback_registrations, test_close_plugin_host};
use serde_json::json;
use tokio_stream::StreamExt;

fn reset_global() {
let _ = clear_plugin_configuration();
let _ = test_close_plugin_host();
let ctx = global_context();
let mut state = ctx.write().unwrap();
*state = NemoRelayContextState::new();
Expand Down
1 change: 1 addition & 0 deletions crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ libc = "0.2"
windows-sys = { version = "0.61", features = ["Win32_Foundation", "Win32_Security", "Win32_Security_Authorization", "Win32_Storage_FileSystem", "Win32_System_Diagnostics_ToolHelp", "Win32_System_JobObjects", "Win32_System_SystemInformation", "Win32_System_Threading"] }

[dev-dependencies]
nemo-relay = { workspace = true, features = ["__test-plugin-host"] }
opentelemetry = { workspace = true, features = ["trace"] }
opentelemetry_sdk = { workspace = true, features = ["trace", "testing"] }
shell-words = "1"
Expand Down
4 changes: 2 additions & 2 deletions crates/cli/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use nemo_relay::api::event::{BaseEvent, Event, MarkEvent};
use nemo_relay::codec::model_pricing::{PricingCatalog, PricingConfig, PricingSourceConfig};
use nemo_relay::observability::otel::resolve_http_trace_endpoint;
use nemo_relay::observability::plugin_component::OBSERVABILITY_PLUGIN_KIND;
use nemo_relay::plugin::{DiagnosticLevel, PluginConfig, validate_plugin_config};
use nemo_relay::plugin::{DiagnosticLevel, PluginConfig, validate_static_plugin_config};
use nemo_relay_adaptive::plugin_component::ADAPTIVE_PLUGIN_KIND;
use nemo_relay_adaptive::{ResponseCacheConfig, response_cache};
use serde_json::{Value, json};
Expand Down Expand Up @@ -633,7 +633,7 @@ async fn collect_observability(gateway: &GatewayConfig, probe_mode: DoctorProbeM
}));
return checks;
}
let report = validate_plugin_config(&plugin_config);
let report = validate_static_plugin_config(&plugin_config);
let response_cache_invalid = report.diagnostics.iter().any(|diagnostic| {
diagnostic.level == DiagnosticLevel::Error
&& diagnostic.component.as_deref().is_some_and(|component| {
Expand Down
4 changes: 2 additions & 2 deletions crates/cli/src/plugins/config_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use std::path::{Path, PathBuf};

use console::style;
use nemo_relay::plugin::{ConfigPolicy, PluginConfig, validate_plugin_config};
use nemo_relay::plugin::{ConfigPolicy, PluginConfig, validate_static_plugin_config};
use serde::Serialize;
use serde_json::{Map, Value};

Expand Down Expand Up @@ -707,7 +707,7 @@ pub(crate) fn validate_config(config: &PluginConfig) -> Result<(), CliError> {
{
return Err(CliError::Config(error.to_string()));
}
let report = validate_plugin_config(config);
let report = validate_static_plugin_config(config);
if report.has_errors() {
let messages = report
.diagnostics
Expand Down
Loading
Loading