Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion src/commands/exp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
//! orx exp run <expId> … launch a local orx-supervised run
//! orx exp cancel <expId> cancel the in-flight run
//! orx exp wake <expId> resume this agent when the run succeeds or fails
//! orx exp archive <expId> --ancestors|--only|--descendants hide the chosen scope
//! orx exp unarchive <expId> --ancestors|--only|--descendants restore the same nodes
//!
//! Unlike the project-scoped data commands, every verb here takes an
//! *experiment* id from `orx project view <projectId>`.
Expand All @@ -16,8 +18,22 @@ use crate::store::Store;
use crate::ExpCommand;

pub async fn run(args: crate::ExpArgs) -> Result<()> {
let store = Store::open()?;
let mut store = Store::open()?;
match args.command {
ExpCommand::Archive {
exp_id,
ancestors,
only,
descendants,
..
} => archive(&mut store, &exp_id, ancestors, only, descendants, true),
ExpCommand::Unarchive {
exp_id,
ancestors,
only,
descendants,
..
} => archive(&mut store, &exp_id, ancestors, only, descendants, false),
ExpCommand::Status { exp_id, scheduler } => {
crate::local::chat::record_chat_target("experiments", &exp_id);
resolve_experiment(store, &exp_id)?
Expand Down Expand Up @@ -47,6 +63,32 @@ pub async fn run(args: crate::ExpArgs) -> Result<()> {
}
}

fn archive(
store: &mut Store,
id: &str,
ancestors: bool,
only: bool,
descendants: bool,
archived: bool,
) -> Result<()> {
let direction = if ancestors {
crate::local::experiments::ArchiveDirection::Ancestors
} else if only {
crate::local::experiments::ArchiveDirection::Only
} else if descendants {
crate::local::experiments::ArchiveDirection::Descendants
} else {
unreachable!("clap requires an archive scope")
};
let ids = crate::local::experiments::set_archived(store, id, direction, archived)?;
println!(
"{} {} experiment(s).",
if archived { "Archived" } else { "Restored" },
ids.len()
);
Ok(())
}

fn wake(store: &Store, exp_id: &str) -> Result<()> {
if !crate::local::chat::in_local_session() {
return Err(anyhow!(
Expand Down
4 changes: 2 additions & 2 deletions src/commands/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use crate::ProjectCommand;

pub async fn run(args: crate::ProjectArgs) -> Result<()> {
match args.command {
ProjectCommand::View { project_id } => {
ProjectCommand::View { project_id, all } => {
let store = crate::store::Store::open()?;
resolve_project(store, &project_id)?.view_project().await
resolve_project(store, &project_id)?.view_project(all).await
}
ProjectCommand::Edit {
project_id,
Expand Down
35 changes: 35 additions & 0 deletions src/commands/up.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,10 @@ fn router(state: AppState, remote_auth: Option<RemoteAuth>) -> Router {
.route("/api/runs/{id}/logs", get(run_logs))
.route("/api/runs/{id}/diff", get(run_diff))
.route("/api/experiments/{id}/diff", get(experiment_diff))
.route(
"/api/experiments/{id}/archive",
axum::routing::patch(set_experiment_archive),
)
.route("/api/experiments/{id}/commits", get(experiment_commits))
.route(
"/api/experiments/{id}/commits/{sha}/diff",
Expand Down Expand Up @@ -1944,6 +1948,37 @@ async fn list_experiments(Path(id): Path<String>) -> ApiResult {
Ok(Json(json!({ "experiments": experiments })))
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct ArchiveExperimentRequest {
direction: String,
archived: bool,
}

async fn set_experiment_archive(
Path(id): Path<String>,
Json(request): Json<ArchiveExperimentRequest>,
) -> ApiResult {
let direction = match request.direction.as_str() {
"ancestors" => local::experiments::ArchiveDirection::Ancestors,
"descendants" => local::experiments::ArchiveDirection::Descendants,
"only" => local::experiments::ArchiveDirection::Only,
"region" => local::experiments::ArchiveDirection::Region,
"taskRegion" => local::experiments::ArchiveDirection::TaskRegion,
_ => {
return Err(bad_request(
"direction must be ancestors, descendants, only, region, or taskRegion",
))
}
};
let mut store = Store::open()?;
if store.get_local_experiment(&id)?.is_none() {
return Err(not_found("experiment"));
}
let ids = local::experiments::set_archived(&mut store, &id, direction, request.archived)?;
Ok(Json(json!({ "ids": ids })))
}

async fn list_project_runs(Path(id): Path<String>) -> ApiResult {
let store = Store::open()?;
store
Expand Down
1 change: 1 addition & 0 deletions src/jobs/ssh/container/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ async fn supervisor_restart(target: &SshTarget, reference: &str, port: u16) {
created_at: 1,
updated_at: 1,
chat_session_id: None,
archived: false,
})
.unwrap();
let (dir, container) = launch(target, Some(reference), "echo ONCE; sleep 8; echo AFTER").await;
Expand Down
3 changes: 3 additions & 0 deletions src/local/demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ fn seed_at(
created_at: ago(seeded_at, 240, 0),
updated_at: ago(seeded_at, 9, 0),
chat_session_id: Some(SESSION_ID.into()),
archived: false,
};
let lr_probe = LocalExperiment {
id: LR_PROBE_EXPERIMENT_ID.into(),
Expand All @@ -487,6 +488,7 @@ fn seed_at(
created_at: ago(seeded_at, 8, 0),
updated_at: ago(seeded_at, 8, 0),
chat_session_id: None,
archived: false,
};
let vocab_probe = LocalExperiment {
id: VOCAB_PROBE_EXPERIMENT_ID.into(),
Expand All @@ -507,6 +509,7 @@ fn seed_at(
created_at: ago(seeded_at, 6, 0),
updated_at: ago(seeded_at, 6, 0),
chat_session_id: None,
archived: false,
};
// created_at and run_ended_at must stay RUN_LOG_SPAN_MIN apart.
let run_ended_at = ago(seeded_at, 10, 0);
Expand Down
Loading
Loading