use std::sync::{Arc, LazyLock};
use std::time::Duration;
use crate::ctx;
pub(crate) struct StubRetrieveClient;
#[async_trait::async_trait]
impl crate::retrieval::retrieve::Client<ctx::DefaultContextExt> for StubRetrieveClient {
async fn get_agent<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: &ctx::Context<ctx::DefaultContextExt, PC>,
_path: &objectiveai_sdk::RemotePath,
) -> Result<Option<objectiveai_sdk::agent::RemoteAgentBaseWithFallbacks>, objectiveai_sdk::error::ResponseError> {
Err(objectiveai_sdk::error::ResponseError {
code: 501,
message: serde_json::json!("stub retrieve client should not be called"),
})
}
async fn get_swarm<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: &ctx::Context<ctx::DefaultContextExt, PC>,
_path: &objectiveai_sdk::RemotePath,
) -> Result<Option<objectiveai_sdk::swarm::RemoteSwarmBase>, objectiveai_sdk::error::ResponseError> {
Err(objectiveai_sdk::error::ResponseError {
code: 501,
message: serde_json::json!("stub retrieve client should not be called"),
})
}
async fn get_function<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: &ctx::Context<ctx::DefaultContextExt, PC>,
_path: &objectiveai_sdk::RemotePath,
) -> Result<Option<objectiveai_sdk::functions::FullRemoteFunction>, objectiveai_sdk::error::ResponseError> {
Err(objectiveai_sdk::error::ResponseError {
code: 501,
message: serde_json::json!("stub retrieve client should not be called"),
})
}
async fn get_profile<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: &ctx::Context<ctx::DefaultContextExt, PC>,
_path: &objectiveai_sdk::RemotePath,
) -> Result<Option<objectiveai_sdk::functions::RemoteProfile>, objectiveai_sdk::error::ResponseError> {
Err(objectiveai_sdk::error::ResponseError {
code: 501,
message: serde_json::json!("stub retrieve client should not be called"),
})
}
async fn get_prompt<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: &ctx::Context<ctx::DefaultContextExt, PC>,
_path: &objectiveai_sdk::RemotePath,
) -> Result<Option<objectiveai_sdk::functions::inventions::prompts::RemotePrompt>, objectiveai_sdk::error::ResponseError> {
Err(objectiveai_sdk::error::ResponseError {
code: 501,
message: serde_json::json!("stub retrieve client should not be called"),
})
}
async fn get_function_invention_state_file<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: &ctx::Context<ctx::DefaultContextExt, PC>,
_path: &objectiveai_sdk::RemotePath,
_filename: &'static str,
) -> Result<Option<String>, objectiveai_sdk::error::ResponseError> {
Err(objectiveai_sdk::error::ResponseError {
code: 501,
message: serde_json::json!("stub retrieve client should not be called"),
})
}
async fn resolve_latest<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: &ctx::Context<ctx::DefaultContextExt, PC>,
_kind: crate::retrieval::Kind,
_path: &objectiveai_sdk::RemotePathCommitOptional,
) -> Result<Option<objectiveai_sdk::RemotePath>, objectiveai_sdk::error::ResponseError> {
Err(objectiveai_sdk::error::ResponseError {
code: 501,
message: serde_json::json!("stub retrieve client should not be called"),
})
}
}
pub(crate) struct StubAgentUsageHandler;
impl crate::agent::completions::usage_handler::UsageHandler<ctx::DefaultContextExt>
for StubAgentUsageHandler
{
fn handle_usage(
&self,
_ctx: ctx::Context<ctx::DefaultContextExt, impl crate::ctx::persistent_cache::PersistentCacheClient>,
_request: Arc<objectiveai_sdk::agent::completions::request::AgentCompletionCreateParams>,
_response: objectiveai_sdk::agent::completions::response::unary::AgentCompletion,
) -> impl std::future::Future<Output = ()> + Send + 'static {
async {}
}
}
pub(crate) struct StubVectorUsageHandler;
#[async_trait::async_trait]
impl crate::vector::completions::usage_handler::UsageHandler<ctx::DefaultContextExt>
for StubVectorUsageHandler
{
async fn handle_usage<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: ctx::Context<ctx::DefaultContextExt, PC>,
_request: Arc<objectiveai_sdk::vector::completions::request::VectorCompletionCreateParams>,
_response: objectiveai_sdk::vector::completions::response::unary::VectorCompletion,
) {
}
}
pub(crate) struct StubFunctionUsageHandler;
#[async_trait::async_trait]
impl crate::functions::executions::usage_handler::UsageHandler<ctx::DefaultContextExt>
for StubFunctionUsageHandler
{
async fn handle_usage<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: ctx::Context<ctx::DefaultContextExt, PC>,
_request: Arc<objectiveai_sdk::functions::executions::request::FunctionExecutionCreateParams>,
_response: objectiveai_sdk::functions::executions::response::unary::FunctionExecution,
) {
}
}
pub(crate) struct StubInventionUsageHandler;
#[async_trait::async_trait]
impl crate::functions::inventions::usage_handler::UsageHandler<ctx::DefaultContextExt>
for StubInventionUsageHandler
{
async fn handle_usage<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: ctx::Context<ctx::DefaultContextExt, PC>,
_request: Arc<objectiveai_sdk::functions::inventions::request::FunctionInventionCreateParams>,
_response: objectiveai_sdk::functions::inventions::response::unary::FunctionInvention,
) {
}
}
pub(crate) struct StubRecursiveUsageHandler;
#[async_trait::async_trait]
impl crate::functions::inventions::recursive::usage_handler::UsageHandler<ctx::DefaultContextExt>
for StubRecursiveUsageHandler
{
async fn handle_usage<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: ctx::Context<ctx::DefaultContextExt, PC>,
_request: Arc<objectiveai_sdk::functions::inventions::recursive::request::FunctionInventionRecursiveCreateParams>,
_response: objectiveai_sdk::functions::inventions::recursive::response::unary::FunctionInventionRecursive,
) {
}
}
pub(crate) struct StubLabUsageHandler;
#[async_trait::async_trait]
impl crate::laboratories::executions::usage_handler::UsageHandler<ctx::DefaultContextExt>
for StubLabUsageHandler
{
async fn handle_usage<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: ctx::Context<ctx::DefaultContextExt, PC>,
_request: Arc<objectiveai_sdk::laboratories::executions::request::LaboratoryExecutionCreateParams>,
_response: objectiveai_sdk::laboratories::executions::response::unary::LaboratoryExecution,
) {
}
}
pub(crate) struct StubCompletionVotesFetcher;
#[async_trait::async_trait]
impl crate::vector::completions::completion_votes_fetcher::Fetcher<ctx::DefaultContextExt>
for StubCompletionVotesFetcher
{
async fn fetch<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: ctx::Context<ctx::DefaultContextExt, PC>,
_id: &str,
) -> Result<
Option<Vec<objectiveai_sdk::vector::completions::response::Vote>>,
objectiveai_sdk::error::ResponseError,
> {
Ok(None)
}
}
pub(crate) struct StubCacheVoteFetcher;
#[async_trait::async_trait]
impl crate::vector::completions::cache_vote_fetcher::Fetcher<ctx::DefaultContextExt>
for StubCacheVoteFetcher
{
async fn fetch<PC: crate::ctx::persistent_cache::PersistentCacheClient>(
&self,
_ctx: ctx::Context<ctx::DefaultContextExt, PC>,
_agent: &objectiveai_sdk::agent::InlineAgentBaseWithFallbacksOrRemote,
_messages: &[objectiveai_sdk::agent::completions::message::Message],
_responses: &[objectiveai_sdk::agent::completions::message::RichContent],
) -> Result<
Option<objectiveai_sdk::vector::completions::response::Vote>,
objectiveai_sdk::error::ResponseError,
> {
Ok(None)
}
}
use crate::agent::completions::UnimplementedUpstreamClient;
pub(crate) type AgentRetrieveRouter = crate::retrieval::retrieve::Router<
StubRetrieveClient,
StubRetrieveClient,
crate::retrieval::retrieve::mock::MockClient,
ctx::DefaultContextExt,
>;
pub(crate) type FunctionRetrieveRouter = crate::retrieval::retrieve::Router<
crate::retrieval::retrieve::mock::MockClient,
crate::retrieval::retrieve::mock::MockClient,
crate::retrieval::retrieve::mock::MockClient,
ctx::DefaultContextExt,
>;
pub(crate) type AgentClient = crate::agent::completions::Client<
ctx::DefaultContextExt,
UnimplementedUpstreamClient,
UnimplementedUpstreamClient,
UnimplementedUpstreamClient,
crate::agent::completions::mock::Client,
StubRetrieveClient,
StubRetrieveClient,
crate::retrieval::retrieve::mock::MockClient,
StubAgentUsageHandler,
>;
pub(crate) type VectorClient = crate::vector::completions::Client<
ctx::DefaultContextExt,
UnimplementedUpstreamClient,
UnimplementedUpstreamClient,
UnimplementedUpstreamClient,
crate::agent::completions::mock::Client,
StubRetrieveClient,
StubRetrieveClient,
crate::retrieval::retrieve::mock::MockClient,
StubAgentUsageHandler,
StubCompletionVotesFetcher,
StubCacheVoteFetcher,
StubVectorUsageHandler,
>;
pub(crate) type FunctionExecutionsClient = crate::functions::executions::Client<
ctx::DefaultContextExt,
UnimplementedUpstreamClient,
UnimplementedUpstreamClient,
UnimplementedUpstreamClient,
crate::agent::completions::mock::Client,
StubAgentUsageHandler,
StubCompletionVotesFetcher,
StubCacheVoteFetcher,
StubVectorUsageHandler,
StubRetrieveClient,
StubRetrieveClient,
crate::retrieval::retrieve::mock::MockClient,
StubFunctionUsageHandler,
>;
pub(crate) type FunctionInventionsClient = crate::functions::inventions::Client<
ctx::DefaultContextExt,
UnimplementedUpstreamClient,
UnimplementedUpstreamClient,
UnimplementedUpstreamClient,
crate::agent::completions::mock::Client,
StubRetrieveClient,
StubRetrieveClient,
crate::retrieval::retrieve::mock::MockClient,
StubAgentUsageHandler,
StubInventionUsageHandler,
crate::retrieval::retrieve::mock::MockClient,
crate::retrieval::retrieve::mock::MockClient,
crate::retrieval::retrieve::mock::MockClient,
>;
pub(crate) type FunctionRecursiveInventionsClient = crate::functions::inventions::recursive::Client<
ctx::DefaultContextExt,
UnimplementedUpstreamClient,
UnimplementedUpstreamClient,
UnimplementedUpstreamClient,
crate::agent::completions::mock::Client,
StubRetrieveClient,
StubRetrieveClient,
crate::retrieval::retrieve::mock::MockClient,
StubAgentUsageHandler,
StubInventionUsageHandler,
crate::retrieval::retrieve::mock::MockClient,
crate::retrieval::retrieve::mock::MockClient,
crate::retrieval::retrieve::mock::MockClient,
StubRecursiveUsageHandler,
>;
pub(crate) type LaboratoryClient = crate::laboratories::executions::Client<
ctx::DefaultContextExt,
UnimplementedUpstreamClient,
UnimplementedUpstreamClient,
UnimplementedUpstreamClient,
crate::agent::completions::mock::Client,
StubRetrieveClient,
StubRetrieveClient,
crate::retrieval::retrieve::mock::MockClient,
StubAgentUsageHandler,
StubLabUsageHandler,
crate::laboratories::orchestrator::mock::Orchestrator,
>;
static BACKGROUND_RUNTIME: LazyLock<tokio::runtime::Runtime> = LazyLock::new(|| {
tokio::runtime::Builder::new_multi_thread()
.worker_threads(2)
.enable_all()
.thread_name("test-clients-bg")
.build()
.expect("build test_clients background runtime")
});
static TEST_PARALLELISM_SEMAPHORE: LazyLock<Arc<tokio::sync::Semaphore>> = LazyLock::new(|| {
let limit: usize = match std::env::var("TOKIO_TEST_PARALLELISM") {
Ok(s) => s.parse().unwrap_or_else(|e| {
panic!("TOKIO_TEST_PARALLELISM must parse as a positive integer: {e}");
}),
Err(_) => 10,
};
Arc::new(tokio::sync::Semaphore::new(limit))
});
pub(crate) async fn acquire_test_permit() -> tokio::sync::OwnedSemaphorePermit {
TEST_PARALLELISM_SEMAPHORE
.clone()
.acquire_owned()
.await
.expect("test parallelism semaphore unexpectedly closed")
}
static MOCK_UPSTREAM: LazyLock<Arc<crate::agent::completions::mock::Client>> = LazyLock::new(|| {
Arc::new(crate::agent::completions::mock::Client {
delay: Duration::ZERO,
max_tool_calls: 1000,
})
});
static AGENT_RETRIEVE_ROUTER: LazyLock<Arc<AgentRetrieveRouter>> = LazyLock::new(|| {
Arc::new(crate::retrieval::retrieve::Router::new(
STUB_RETRIEVE_CLIENT.clone(),
STUB_RETRIEVE_CLIENT.clone(),
MOCK_RETRIEVE_CLIENT.clone(),
))
});
static FUNCTION_RETRIEVE_ROUTER: LazyLock<Arc<FunctionRetrieveRouter>> = LazyLock::new(|| {
Arc::new(crate::retrieval::retrieve::Router::new(
MOCK_RETRIEVE_CLIENT.clone(),
MOCK_RETRIEVE_CLIENT.clone(),
MOCK_RETRIEVE_CLIENT.clone(),
))
});
static VIEWER_CLIENT: LazyLock<Arc<crate::viewer::Client<ctx::DefaultContextExt>>> = LazyLock::new(|| {
Arc::new(crate::viewer::Client::new(
reqwest::Client::new(),
None,
None,
Duration::ZERO,
Duration::ZERO,
0.0,
1.0,
Duration::ZERO,
Duration::from_millis(1),
))
});
static GITHUB_CLIENT: LazyLock<Arc<crate::github::Client>> = LazyLock::new(|| {
Arc::new(crate::github::Client::new(
reqwest::Client::new(),
None,
false,
String::new(),
String::new(),
String::new(),
Duration::ZERO,
Duration::ZERO,
0.0,
1.0,
Duration::ZERO,
Duration::ZERO,
))
});
static FILESYSTEM_CLIENT: LazyLock<Arc<crate::filesystem::Client>> = LazyLock::new(|| {
Arc::new(crate::filesystem::Client::new(
std::path::PathBuf::from("/tmp/objectiveai-test"),
"ObjectiveAI".to_string(),
"noreply@objectiveai.dev".to_string(),
))
});
const MCP_CONNECT_TIMEOUT_MS: u64 = 30_000;
const MCP_CALL_TIMEOUT_MS: u64 = 30_000;
const MCP_BACKOFF_CURRENT_INTERVAL_MS: u64 = 100;
const MCP_BACKOFF_INITIAL_INTERVAL_MS: u64 = 100;
const MCP_BACKOFF_RANDOMIZATION_FACTOR: f64 = 0.5;
const MCP_BACKOFF_MULTIPLIER: f64 = 1.5;
const MCP_BACKOFF_MAX_INTERVAL_MS: u64 = 1_000;
const MCP_BACKOFF_MAX_ELAPSED_TIME_MS: u64 = 40_000;
static MCP_CLIENT: LazyLock<Arc<objectiveai_sdk::mcp::Client>> = LazyLock::new(|| {
let _guard = BACKGROUND_RUNTIME.handle().enter();
let reqwest = reqwest::Client::builder()
.build()
.expect("build reqwest::Client");
drop(_guard);
Arc::new(objectiveai_sdk::mcp::Client::new(
reqwest,
String::new(),
String::new(),
String::new(),
Duration::from_millis(MCP_CONNECT_TIMEOUT_MS),
Duration::from_millis(MCP_BACKOFF_CURRENT_INTERVAL_MS),
Duration::from_millis(MCP_BACKOFF_INITIAL_INTERVAL_MS),
MCP_BACKOFF_RANDOMIZATION_FACTOR,
MCP_BACKOFF_MULTIPLIER,
Duration::from_millis(MCP_BACKOFF_MAX_INTERVAL_MS),
Duration::from_millis(MCP_BACKOFF_MAX_ELAPSED_TIME_MS),
Duration::from_millis(MCP_CALL_TIMEOUT_MS),
))
});
static PROXY_SPAWNER: LazyLock<Arc<crate::agent::completions::ProxySpawner>> = LazyLock::new(|| {
Arc::new(crate::agent::completions::ProxySpawner::new_with_handle(
BACKGROUND_RUNTIME.handle().clone(),
|| objectiveai_mcp_proxy::ConfigBuilder {
mcp_connect_timeout: Some(MCP_CONNECT_TIMEOUT_MS),
mcp_call_timeout: Some(MCP_CALL_TIMEOUT_MS),
mcp_backoff_current_interval: Some(MCP_BACKOFF_CURRENT_INTERVAL_MS),
mcp_backoff_initial_interval: Some(MCP_BACKOFF_INITIAL_INTERVAL_MS),
mcp_backoff_randomization_factor: Some(MCP_BACKOFF_RANDOMIZATION_FACTOR),
mcp_backoff_multiplier: Some(MCP_BACKOFF_MULTIPLIER),
mcp_backoff_max_interval: Some(MCP_BACKOFF_MAX_INTERVAL_MS),
mcp_backoff_max_elapsed_time: Some(MCP_BACKOFF_MAX_ELAPSED_TIME_MS),
..Default::default()
},
))
});
static INVENTION_SERVER_SPAWNER: LazyLock<Arc<crate::functions::inventions::InventionServerSpawner>> =
LazyLock::new(|| {
Arc::new(crate::functions::inventions::InventionServerSpawner::new_with_handle(
BACKGROUND_RUNTIME.handle().clone(),
))
});
static STUB_RETRIEVE_CLIENT: LazyLock<Arc<StubRetrieveClient>> =
LazyLock::new(|| Arc::new(StubRetrieveClient));
static MOCK_RETRIEVE_CLIENT: LazyLock<Arc<crate::retrieval::retrieve::mock::MockClient>> =
LazyLock::new(|| Arc::new(crate::retrieval::retrieve::mock::MockClient));
static STUB_AGENT_USAGE_HANDLER: LazyLock<Arc<StubAgentUsageHandler>> =
LazyLock::new(|| Arc::new(StubAgentUsageHandler));
static STUB_VECTOR_USAGE_HANDLER: LazyLock<Arc<StubVectorUsageHandler>> =
LazyLock::new(|| Arc::new(StubVectorUsageHandler));
static STUB_FUNCTION_USAGE_HANDLER: LazyLock<Arc<StubFunctionUsageHandler>> =
LazyLock::new(|| Arc::new(StubFunctionUsageHandler));
static STUB_INVENTION_USAGE_HANDLER: LazyLock<Arc<StubInventionUsageHandler>> =
LazyLock::new(|| Arc::new(StubInventionUsageHandler));
static STUB_RECURSIVE_USAGE_HANDLER: LazyLock<Arc<StubRecursiveUsageHandler>> =
LazyLock::new(|| Arc::new(StubRecursiveUsageHandler));
static STUB_LAB_USAGE_HANDLER: LazyLock<Arc<StubLabUsageHandler>> =
LazyLock::new(|| Arc::new(StubLabUsageHandler));
static STUB_COMPLETION_VOTES_FETCHER: LazyLock<Arc<StubCompletionVotesFetcher>> =
LazyLock::new(|| Arc::new(StubCompletionVotesFetcher));
static STUB_CACHE_VOTE_FETCHER: LazyLock<Arc<StubCacheVoteFetcher>> =
LazyLock::new(|| Arc::new(StubCacheVoteFetcher));
static UNIMPLEMENTED_OPENROUTER: LazyLock<Arc<UnimplementedUpstreamClient>> =
LazyLock::new(|| Arc::new(UnimplementedUpstreamClient));
static UNIMPLEMENTED_CLAUDE_AGENT_SDK: LazyLock<Arc<UnimplementedUpstreamClient>> =
LazyLock::new(|| Arc::new(UnimplementedUpstreamClient));
static UNIMPLEMENTED_CODEX_SDK: LazyLock<Arc<UnimplementedUpstreamClient>> =
LazyLock::new(|| Arc::new(UnimplementedUpstreamClient));
static MOCK_ORCHESTRATOR: LazyLock<Arc<crate::laboratories::orchestrator::mock::Orchestrator>> =
LazyLock::new(|| Arc::new(crate::laboratories::orchestrator::mock::Orchestrator));
static AGENT: LazyLock<Arc<AgentClient>> = LazyLock::new(|| {
Arc::new(crate::agent::completions::Client::new(
MCP_CLIENT.clone(),
PROXY_SPAWNER.clone(),
None,
AGENT_RETRIEVE_ROUTER.clone(),
STUB_AGENT_USAGE_HANDLER.clone(),
UNIMPLEMENTED_OPENROUTER.clone(),
UNIMPLEMENTED_CLAUDE_AGENT_SDK.clone(),
UNIMPLEMENTED_CODEX_SDK.clone(),
MOCK_UPSTREAM.clone(),
VIEWER_CLIENT.clone(),
Duration::ZERO,
Duration::ZERO,
0.0,
1.0,
Duration::ZERO,
Duration::ZERO,
Duration::from_secs(1800),
Duration::from_secs(1800),
))
});
static VECTOR: LazyLock<Arc<VectorClient>> = LazyLock::new(|| {
Arc::new(crate::vector::completions::Client::new(
AGENT.clone(),
AGENT_RETRIEVE_ROUTER.clone(),
STUB_COMPLETION_VOTES_FETCHER.clone(),
STUB_CACHE_VOTE_FETCHER.clone(),
STUB_VECTOR_USAGE_HANDLER.clone(),
))
});
static FUNCTION_EXECUTIONS: LazyLock<Arc<FunctionExecutionsClient>> = LazyLock::new(|| {
Arc::new(crate::functions::executions::Client::new(
AGENT.clone(),
VECTOR.clone(),
VIEWER_CLIENT.clone(),
AGENT_RETRIEVE_ROUTER.clone(),
STUB_FUNCTION_USAGE_HANDLER.clone(),
))
});
static FUNCTION_INVENTIONS: LazyLock<Arc<FunctionInventionsClient>> = LazyLock::new(|| {
Arc::new(crate::functions::inventions::Client::new(
AGENT.clone(),
GITHUB_CLIENT.clone(),
FILESYSTEM_CLIENT.clone(),
FUNCTION_RETRIEVE_ROUTER.clone(),
STUB_INVENTION_USAGE_HANDLER.clone(),
INVENTION_SERVER_SPAWNER.clone(),
true,
false,
std::time::Duration::from_secs(30),
))
});
static FUNCTION_RECURSIVE_INVENTIONS: LazyLock<Arc<FunctionRecursiveInventionsClient>> = LazyLock::new(|| {
Arc::new(crate::functions::inventions::recursive::Client::new(
FUNCTION_INVENTIONS.clone(),
VIEWER_CLIENT.clone(),
STUB_RECURSIVE_USAGE_HANDLER.clone(),
))
});
static LABORATORY: LazyLock<Arc<LaboratoryClient>> = LazyLock::new(|| {
Arc::new(crate::laboratories::executions::Client {
agent_client: AGENT.clone(),
retrieve_router: AGENT_RETRIEVE_ROUTER.clone(),
usage_handler: STUB_LAB_USAGE_HANDLER.clone(),
viewer: VIEWER_CLIENT.clone(),
orchestrator: MOCK_ORCHESTRATOR.clone(),
})
});
pub(crate) fn mock_upstream() -> Arc<crate::agent::completions::mock::Client> {
MOCK_UPSTREAM.clone()
}
pub(crate) fn proxy_spawner() -> Arc<crate::agent::completions::ProxySpawner> {
PROXY_SPAWNER.clone()
}
pub(crate) fn run_test<F: std::future::Future>(fut: F) -> F::Output {
BACKGROUND_RUNTIME.block_on(fut)
}
pub(crate) fn invention_server_spawner() -> Arc<crate::functions::inventions::InventionServerSpawner> {
INVENTION_SERVER_SPAWNER.clone()
}
pub(crate) fn mcp_client() -> Arc<objectiveai_sdk::mcp::Client> {
MCP_CLIENT.clone()
}
pub(crate) fn agent() -> Arc<AgentClient> {
AGENT.clone()
}
pub(crate) fn vector() -> Arc<VectorClient> {
VECTOR.clone()
}
pub(crate) fn function_executions() -> Arc<FunctionExecutionsClient> {
FUNCTION_EXECUTIONS.clone()
}
pub(crate) fn function_inventions() -> Arc<FunctionInventionsClient> {
FUNCTION_INVENTIONS.clone()
}
pub(crate) fn function_recursive_inventions() -> Arc<FunctionRecursiveInventionsClient> {
FUNCTION_RECURSIVE_INVENTIONS.clone()
}
pub(crate) fn laboratory() -> Arc<LaboratoryClient> {
LABORATORY.clone()
}