algocline_app/service/
mod.rs1mod config;
2mod engine_api_impl;
3mod eval;
4mod eval_store;
5pub(crate) mod lockfile;
6mod logging;
7pub(crate) mod manifest;
8pub(crate) mod path;
9mod pkg;
10mod pkg_link;
11pub(crate) mod project;
12pub mod resolve;
13mod run;
14mod scenario;
15pub(crate) mod source;
16mod status;
17mod transcript;
18
19#[cfg(test)]
20mod tests;
21
22use std::path::Path;
23use std::sync::Arc;
24
25use algocline_engine::{Executor, SessionRegistry};
26
27pub use algocline_core::{EngineApi, TokenUsage};
28pub use config::{AppConfig, LogDirSource};
29pub use resolve::{QueryResponse, SearchPath};
30
31type EvalSessions = std::sync::Mutex<std::collections::HashMap<String, String>>;
41
42type SessionStrategies = std::sync::Mutex<std::collections::HashMap<String, String>>;
48
49#[derive(Clone)]
50pub struct AppService {
51 executor: Arc<Executor>,
52 registry: Arc<SessionRegistry>,
53 log_config: AppConfig,
54 search_paths: Vec<resolve::SearchPath>,
56 eval_sessions: Arc<EvalSessions>,
58 session_strategies: Arc<SessionStrategies>,
60}
61
62impl AppService {
63 pub fn new(
64 executor: Arc<Executor>,
65 log_config: AppConfig,
66 search_paths: Vec<resolve::SearchPath>,
67 ) -> Self {
68 let registry = Arc::new(SessionRegistry::new());
69 registry.spawn_gc_task(std::time::Duration::from_secs(10800));
72 Self {
73 executor,
74 registry,
75 log_config,
76 search_paths,
77 eval_sessions: Arc::new(std::sync::Mutex::new(std::collections::HashMap::new())),
78 session_strategies: Arc::new(std::sync::Mutex::new(std::collections::HashMap::new())),
79 }
80 }
81
82 fn require_log_dir(&self) -> Result<&Path, String> {
84 self.log_config
85 .log_dir
86 .as_deref()
87 .ok_or_else(|| "File logging is not available (no writable log directory)".to_string())
88 }
89
90 pub(crate) fn resolve_extra_lib_paths(
100 &self,
101 project_root: Option<&str>,
102 ) -> Vec<std::path::PathBuf> {
103 let Some(root) = project::resolve_project_root(project_root) else {
104 return vec![];
105 };
106
107 match lockfile::load_lockfile(&root) {
108 Ok(Some(lock)) => lockfile::resolve_local_dir_paths(&root, &lock),
109 Ok(None) => vec![],
110 Err(e) => {
111 tracing::warn!("failed to load alc.lock at {}: {e}", root.display());
112 vec![]
113 }
114 }
115 }
116}