#![allow(
clippy::expect_used,
clippy::unwrap_used,
clippy::panic,
clippy::uninlined_format_args,
clippy::collapsible_if,
clippy::redundant_clone,
clippy::needless_raw_string_hashes,
clippy::single_match,
clippy::redundant_closure_for_method_calls,
clippy::redundant_pattern_matching,
clippy::ignored_unit_patterns,
clippy::clone_on_copy,
clippy::manual_assert,
clippy::unwrap_in_result,
clippy::useless_vec
)]
use std::sync::Arc;
use std::time::Duration;
use meerkat_client::TestClient;
use meerkat_mob::ids::MeerkatId;
use meerkat_mob::{MobDefinition, ProfileName, SpawnMemberSpec};
use meerkat_mobkit::{
AuthPolicy, BigQueryNaming, ConsolePolicy, DiscoverySpec, MobKitConfig, PreSpawnData,
RuntimeDecisionInputs, RuntimeOpsPolicy, SubscribeRequest, TrustedOidcRuntimeConfig,
UnifiedRuntime, build_runtime_decision_state, handle_console_ingress_json,
};
const MINIMAL_MOB_TOML: &str = r#"
[mob]
id = "reference-mob"
[profiles.lead]
model = "gpt-5.2"
external_addressable = true
[profiles.lead.tools]
comms = true
"#;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let definition = MobDefinition::from_toml(MINIMAL_MOB_TOML)
.map_err(|e| std::io::Error::other(format!("bad mob definition: {e}")))?;
let runtime = UnifiedRuntime::builder()
.definition(definition)
.default_llm_client(Arc::new(TestClient::default()))
.module_config(MobKitConfig {
modules: vec![],
discovery: DiscoverySpec {
namespace: "reference-app".to_string(),
modules: vec![],
},
pre_spawn: Vec::<PreSpawnData>::new(),
})
.timeout(Duration::from_secs(5))
.build()
.await?;
runtime.reconcile(reference_member_specs()).await?;
runtime
.subscribe_events(SubscribeRequest::default())
.await?;
let decisions = build_runtime_decision_state(RuntimeDecisionInputs {
bigquery: BigQueryNaming {
dataset: "reference_app_dataset".to_string(),
table: "reference_app_table".to_string(),
},
trusted_mobkit_toml: trusted_modules_toml(),
auth: AuthPolicy::default(),
trusted_oidc: trusted_oidc(),
console: ConsolePolicy {
require_app_auth: false,
..ConsolePolicy::default()
},
ops: RuntimeOpsPolicy::default(),
release_metadata_json: include_str!("../assets/release-targets.json").to_string(),
})
.map_err(|err| std::io::Error::other(format!("failed to build console decisions: {err:?}")))?;
let _console_ingress_preview = handle_console_ingress_json(
&decisions,
r#"{"method":"GET","path":"/console/modules","auth":null}"#,
);
let _console_router = runtime.build_console_json_router(decisions.clone());
let listen_addr =
std::env::var("MOBKIT_REF_ADDR").unwrap_or_else(|_| "127.0.0.1:3210".to_string());
let listener = tokio::net::TcpListener::bind(&listen_addr).await?;
println!("reference app listening on http://{listen_addr}");
println!("GET /console");
println!("GET /console/experience");
println!("GET /console/modules");
if std::env::var("MOBKIT_REF_HTTP_MODE").ok().as_deref() == Some("serve") {
runtime.serve(listener, decisions).await?;
return Ok(());
}
let run_report = runtime
.run(listener, decisions, async {
let _ = tokio::signal::ctrl_c().await;
})
.await;
let shutdown = run_report.shutdown;
if shutdown.module_shutdown.orphan_processes != 0 {
return Err(std::io::Error::other(format!(
"runtime shutdown left {} orphan process(es)",
shutdown.module_shutdown.orphan_processes
))
.into());
}
shutdown
.mob_stop
.map_err(|err| std::io::Error::other(format!("failed to stop mob runtime: {err}")))?;
run_report.serve_result?;
Ok(())
}
fn reference_member_specs() -> Vec<SpawnMemberSpec> {
use std::collections::BTreeMap;
fn labels(pairs: &[(&str, &str)]) -> BTreeMap<String, String> {
pairs
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect()
}
vec![
SpawnMemberSpec::new(ProfileName::from("lead"), MeerkatId::from("triage:main"))
.with_labels(labels(&[
("display_name", "Triage"),
("group", "Coordinators"),
])),
SpawnMemberSpec::new(ProfileName::from("lead"), MeerkatId::from("router:main"))
.with_labels(labels(&[
("display_name", "Router"),
("group", "Coordinators"),
])),
SpawnMemberSpec::new(ProfileName::from("lead"), MeerkatId::from("domain:billing"))
.with_labels(labels(&[("display_name", "Billing"), ("group", "Domain")])),
SpawnMemberSpec::new(
ProfileName::from("lead"),
MeerkatId::from("domain:delivery"),
)
.with_labels(labels(&[("display_name", "Delivery"), ("group", "Domain")])),
SpawnMemberSpec::new(ProfileName::from("lead"), MeerkatId::from("domain:support"))
.with_labels(labels(&[("display_name", "Support"), ("group", "Domain")])),
SpawnMemberSpec::new(ProfileName::from("lead"), MeerkatId::from("gate:main")).with_labels(
labels(&[
("display_name", "Gate"),
("group", "Internal"),
("addressable", "false"),
("singleton", "true"),
]),
),
SpawnMemberSpec::new(ProfileName::from("lead"), MeerkatId::from("monitor:health"))
.with_labels(labels(&[
("display_name", "Health Monitor"),
("group", "Internal"),
("addressable", "false"),
("singleton", "true"),
])),
]
}
fn trusted_modules_toml() -> String {
r#"
[[modules]]
id = "router"
command = "router-bin"
args = ["--mode", "fast"]
restart_policy = "always"
[[modules]]
id = "delivery"
command = "delivery-bin"
args = ["--sink", "memory"]
restart_policy = "on_failure"
"#
.to_string()
}
fn trusted_oidc() -> TrustedOidcRuntimeConfig {
TrustedOidcRuntimeConfig {
discovery_json:
r#"{"issuer":"https://trusted.mobkit.local","jwks_uri":"https://trusted.mobkit.local/.well-known/jwks.json"}"#
.to_string(),
jwks_json: r#"{"keys":[{"kid":"kid-current","kty":"oct","alg":"HS256","k":"cGhhc2U3LXRydXN0ZWQtY3VycmVudC1zZWNyZXQ"}]}"#
.to_string(),
audience: "meerkat-console".to_string(),
}
}