agent-style workers
This commit is contained in:
@@ -113,6 +113,10 @@ async fn main() -> Result<()> {
|
||||
let runtime_list: Vec<&str> = detected.iter().map(|r| r.name.as_str()).collect();
|
||||
let runtime_csv = runtime_list.join(",");
|
||||
info!("Setting ATTUNE_WORKER_RUNTIMES={}", runtime_csv);
|
||||
// SAFETY: std::env::set_var is safe in Rust 2021 edition. If upgrading
|
||||
// to edition 2024+, this call will need to be wrapped in `unsafe {}`.
|
||||
// It's sound here because detection runs single-threaded before tokio
|
||||
// starts any worker tasks.
|
||||
std::env::set_var("ATTUNE_WORKER_RUNTIMES", &runtime_csv);
|
||||
|
||||
// Stash for Phase 2: pass to WorkerService for rich capability registration
|
||||
@@ -133,9 +137,10 @@ async fn main() -> Result<()> {
|
||||
println!();
|
||||
let detected = detect_runtimes();
|
||||
print_detection_report(&detected);
|
||||
} else if let Some(ref detected) = agent_detected_runtimes {
|
||||
print_detection_report(detected);
|
||||
} else {
|
||||
// We already ran detection above; re-run to get a fresh Vec for the report
|
||||
// (the previous one was consumed by env var setup).
|
||||
// No detection ran (empty results), run it fresh
|
||||
let detected = detect_runtimes();
|
||||
print_detection_report(&detected);
|
||||
}
|
||||
@@ -144,6 +149,7 @@ async fn main() -> Result<()> {
|
||||
|
||||
// --- Phase 2: Load configuration ---
|
||||
if let Some(config_path) = args.config {
|
||||
// SAFETY: std::env::set_var is safe in Rust 2021 edition. See note above.
|
||||
std::env::set_var("ATTUNE_CONFIG", config_path);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ use attune_common::models::runtime::RuntimeExecutionConfig;
|
||||
use attune_common::models::{runtime::Runtime as RuntimeModel, Action, Execution, ExecutionStatus};
|
||||
use attune_common::repositories::artifact::{ArtifactRepository, ArtifactVersionRepository};
|
||||
use attune_common::repositories::execution::{ExecutionRepository, UpdateExecutionInput};
|
||||
use attune_common::repositories::runtime::SELECT_COLUMNS as RUNTIME_SELECT_COLUMNS;
|
||||
use attune_common::repositories::runtime_version::RuntimeVersionRepository;
|
||||
use attune_common::repositories::{FindById, Update};
|
||||
use attune_common::version_matching::select_best_version;
|
||||
@@ -410,16 +411,14 @@ impl ActionExecutor {
|
||||
|
||||
// Load runtime information if specified
|
||||
let runtime_record = if let Some(runtime_id) = action.runtime {
|
||||
match sqlx::query_as::<_, RuntimeModel>(
|
||||
r#"SELECT id, ref, pack, pack_ref, description, name,
|
||||
distributions, installation, installers, execution_config,
|
||||
auto_detected, detection_config,
|
||||
created, updated
|
||||
FROM runtime WHERE id = $1"#,
|
||||
)
|
||||
.bind(runtime_id)
|
||||
.fetch_optional(&self.pool)
|
||||
.await
|
||||
let query = format!(
|
||||
"SELECT {} FROM runtime WHERE id = $1",
|
||||
RUNTIME_SELECT_COLUMNS
|
||||
);
|
||||
match sqlx::query_as::<_, RuntimeModel>(&query)
|
||||
.bind(runtime_id)
|
||||
.fetch_optional(&self.pool)
|
||||
.await
|
||||
{
|
||||
Ok(Some(runtime)) => {
|
||||
debug!(
|
||||
|
||||
@@ -393,4 +393,72 @@ mod tests {
|
||||
|
||||
registration.deregister().await.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_detected_runtimes_json_structure() {
|
||||
// Test the JSON structure that set_detected_runtimes builds
|
||||
let runtimes = vec![
|
||||
DetectedRuntime {
|
||||
name: "python".to_string(),
|
||||
path: "/usr/bin/python3".to_string(),
|
||||
version: Some("3.12.1".to_string()),
|
||||
},
|
||||
DetectedRuntime {
|
||||
name: "shell".to_string(),
|
||||
path: "/bin/bash".to_string(),
|
||||
version: None,
|
||||
},
|
||||
];
|
||||
|
||||
let interpreters: Vec<serde_json::Value> = runtimes
|
||||
.iter()
|
||||
.map(|rt| {
|
||||
json!({
|
||||
"name": rt.name,
|
||||
"path": rt.path,
|
||||
"version": rt.version,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
let json_value = json!(interpreters);
|
||||
|
||||
// Verify structure
|
||||
let arr = json_value.as_array().unwrap();
|
||||
assert_eq!(arr.len(), 2);
|
||||
assert_eq!(arr[0]["name"], "python");
|
||||
assert_eq!(arr[0]["path"], "/usr/bin/python3");
|
||||
assert_eq!(arr[0]["version"], "3.12.1");
|
||||
assert_eq!(arr[1]["name"], "shell");
|
||||
assert_eq!(arr[1]["path"], "/bin/bash");
|
||||
assert!(arr[1]["version"].is_null());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_detected_runtimes_empty() {
|
||||
let runtimes: Vec<DetectedRuntime> = vec![];
|
||||
let interpreters: Vec<serde_json::Value> = runtimes
|
||||
.iter()
|
||||
.map(|rt| {
|
||||
json!({
|
||||
"name": rt.name,
|
||||
"path": rt.path,
|
||||
"version": rt.version,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
let json_value = json!(interpreters);
|
||||
assert_eq!(json_value.as_array().unwrap().len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_agent_mode_capability_value() {
|
||||
// Verify the JSON value for agent_mode capability
|
||||
let value = json!(true);
|
||||
assert_eq!(value, true);
|
||||
|
||||
let value = json!(false);
|
||||
assert_eq!(value, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user