use anda_core::Principal;
use anda_db::{database::DBConfig, storage::StorageConfig};
use anda_engine::{
management::{BaseManagement, Visibility},
model::{CompletionFeaturesDyn, Model, Models, reqwest},
unix_ms,
};
use cose2::{CoseMap, Label, Sign1Message, Value, cwt::Claims, iana};
use ic_auth_types::ByteBufB64;
use ic_cose_types::cose::ed25519::{SigningKey, VerifyingKey, ed25519_sign};
use object_store::memory::InMemory;
use std::{collections::BTreeSet, sync::Arc};
use crate::{
agents::SELF_USER_ID,
space::{AppState, Space},
};
pub(crate) fn db_config(name: &str) -> DBConfig {
DBConfig {
name: name.to_string(),
description: "test database".to_string(),
storage: StorageConfig::default(),
lock: None,
}
}
pub(crate) fn app_state_core(
name: &str,
models: Arc<Models>,
ed25519_pubkeys: Vec<VerifyingKey>,
app_version: &str,
sharding: u32,
) -> AppState {
let management = Arc::new(BaseManagement {
controller: SELF_USER_ID,
managers: BTreeSet::new(),
visibility: Visibility::Public,
});
let http_client = reqwest::Client::builder().build().unwrap();
AppState::new(
Arc::new(InMemory::new()),
Arc::new(db_config(name)),
management,
http_client,
models,
Arc::new(ed25519_pubkeys),
"anda_brain".to_string(),
app_version.to_string(),
sharding,
)
}
pub(crate) fn models_with_completer(completer: impl CompletionFeaturesDyn) -> Arc<Models> {
models_with_configured_completer(completer, |_| {})
}
pub(crate) fn models_with_configured_completer(
completer: impl CompletionFeaturesDyn,
configure: impl FnOnce(&mut Model),
) -> Arc<Models> {
let models = Models::default();
let mut model = Model::with_completer(Arc::new(completer));
configure(&mut model);
models.set_model(model);
Arc::new(models)
}
pub(crate) async fn create_loaded_space(app: &AppState, id: &str) -> Arc<Space> {
app.admin_create_space(
Principal::from_slice(&[1]),
Principal::from_slice(&[2]),
id.to_string(),
1,
unix_ms(),
)
.await
.unwrap();
app.load_space_with(id, false, false).await.unwrap()
}
pub(crate) fn signing_key(seed: u8) -> SigningKey {
SigningKey::from_bytes(&[seed; 32])
}
pub(crate) fn signed_token(
signing_key: &SigningKey,
user: Principal,
audience: &str,
scope: &str,
) -> String {
signed_token_for(signing_key, user, Some(audience), scope)
}
pub(crate) fn signed_token_for(
signing_key: &SigningKey,
user: Principal,
audience: Option<&str>,
scope: &str,
) -> String {
let claims = Claims {
subject: Some(user.to_string()),
audience: audience.map(|audience| audience.to_string().into()),
extra: CoseMap::from_iter([(
Label::Int(iana::CWTClaimScope),
Value::Text(scope.to_string()),
)]),
..Default::default()
};
let payload = claims.to_vec().unwrap();
let mut sign1 = Sign1Message::new(Some(payload));
let tbs_data = sign1
.prepare_signature(Some(Label::Int(iana::AlgorithmEdDSA)), None, None)
.unwrap();
sign1
.set_signature(
ed25519_sign(signing_key.as_bytes(), &tbs_data)
.to_bytes()
.to_vec(),
)
.unwrap();
ByteBufB64(sign1.to_vec().unwrap()).to_string()
}
pub(crate) async fn declare_types(space: &crate::space::Space, types: &[&str]) {
crate::vocabulary::DeclareSymbolsTool::new(space.memory.clone())
.declare(&crate::vocabulary::DeclareSymbolsArgs {
types: types.iter().map(|name| name.to_string()).collect(),
predicates: vec![],
})
.await
.unwrap();
}