Skip to content

Commit 5875139

Browse files
authored
Merge pull request #33 from altaidevorg/postmortem-fixes
Postmortem fixes
2 parents eb69794 + 27f2aa2 commit 5875139

12 files changed

Lines changed: 1448 additions & 231 deletions

File tree

Cargo.lock

Lines changed: 598 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "isanagent"
3-
version = "0.3.1"
3+
version = "0.4.0"
44
edition = "2021"
55
license = "Apache-2.0"
66
repository = "https://github.com/altaidevorg/isanagent"
@@ -60,6 +60,8 @@ pulldown-cmark = "0.12"
6060
unicode-width = "0.2"
6161
arboard = { version = "3.4", default-features = false }
6262
russh = { version = "0.60", default-features = false, features = ["flate2", "ring", "rsa"] }
63+
htmd = "0.5.4"
64+
pdf_oxide = "0.3.37"
6365

6466
[target.'cfg(unix)'.dependencies]
6567
libc = "0.2"

src/execution/execution_jobs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,7 +1386,7 @@ mod tests {
13861386
std::path::PathBuf,
13871387
) {
13881388
let (ws, dir) = temp_workspace();
1389-
let cfg = LocalExecutionConfig::new(dir.clone(), true);
1389+
let cfg = LocalExecutionConfig::new(dir.clone(), dir.clone(), true);
13901390
let prov: Arc<dyn crate::execution::ExecutionProvider> =
13911391
Arc::new(LocalExecutionProvider::new(cfg).expect("local provider"));
13921392
let harness = Arc::new(ExecutionHarness::new(
@@ -1415,7 +1415,7 @@ mod tests {
14151415
mpsc::Receiver<BusMessage>,
14161416
) {
14171417
let (ws, dir) = temp_workspace();
1418-
let cfg = LocalExecutionConfig::new(dir.clone(), true);
1418+
let cfg = LocalExecutionConfig::new(dir.clone(), dir.clone(), true);
14191419
let prov: Arc<dyn crate::execution::ExecutionProvider> =
14201420
Arc::new(LocalExecutionProvider::new(cfg).expect("local provider"));
14211421
let harness = Arc::new(ExecutionHarness::new(

src/execution/harness.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ fn try_build_provider(
296296
};
297297
let lc = LocalExecutionConfig {
298298
sandbox_dir: sandbox_dir.to_path_buf(),
299+
workspace_dir: workspace_dir.to_path_buf(),
299300
restrict_to_workspace,
300301
max_run_timeout_secs: config.execution_max_wall_secs(),
301302
max_output_bytes: config.execution_max_output_bytes(),

src/execution/local.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use super::ids::SessionId;
2424
use super::provider::ExecutionProvider;
2525
use super::repl_framing::{self, string_from_utf8_lossy_trim_cap, PYTHON_REPL_BOOTSTRAP};
2626
use super::run::{CwdPolicy, RunResult, RunSpec, SessionCreateRequest, SessionHandle};
27+
use super::run_history_dir;
2728
use crate::tool_runtime::emit_tool_progress_message;
2829
use crate::tools::builtin::resolve_path;
2930

@@ -66,10 +67,12 @@ pub struct LocalExecutionConfig {
6667
pub uv_requirements: Vec<String>,
6768
/// Root for UV-managed runtime cache (e.g. workspace `.system_generated/uv/envs`).
6869
pub uv_env_root: PathBuf,
70+
/// Workspace root for log files.
71+
pub workspace_dir: PathBuf,
6972
}
7073

7174
impl LocalExecutionConfig {
72-
pub fn new(sandbox_dir: PathBuf, restrict_to_workspace: bool) -> Self {
75+
pub fn new(sandbox_dir: PathBuf, workspace_dir: PathBuf, restrict_to_workspace: bool) -> Self {
7376
let uv_env_root = sandbox_dir
7477
.join(".system_generated")
7578
.join("uv")
@@ -87,6 +90,7 @@ impl LocalExecutionConfig {
8790
uv_python: "3.11".to_string(),
8891
uv_requirements: Vec::new(),
8992
uv_env_root,
93+
workspace_dir,
9094
}
9195
}
9296
}
@@ -691,10 +695,21 @@ impl ExecutionProvider for LocalExecutionProvider {
691695
let repl = g
692696
.as_mut()
693697
.ok_or_else(|| ExecutionError::Provider("local repl unavailable".into()))?;
698+
let mut stdout_path = None;
699+
let mut stderr_path = None;
700+
let hd;
701+
if let Some(rid) = &spec.run_id {
702+
hd = run_history_dir(&self.config.workspace_dir, "local", session_id, rid);
703+
let _ = tokio::fs::create_dir_all(&hd).await;
704+
stdout_path = Some(hd.join("stdout.txt"));
705+
stderr_path = Some(hd.join("stderr.txt"));
706+
}
694707
let (stdout, stderr, st) = repl_framing::repl_round_trip(
695708
&mut repl.stdin,
696709
&mut repl.stdout,
697710
&code,
711+
stdout_path.as_deref(),
712+
stderr_path.as_deref(),
698713
max_each,
699714
)
700715
.await?;
@@ -1027,6 +1042,7 @@ mod tests {
10271042
#[tokio::test]
10281043
async fn rejects_non_dir_sandbox() {
10291044
let cfg = LocalExecutionConfig::new(
1045+
PathBuf::from("/nonexistent/path/that/should/not/exist"),
10301046
PathBuf::from("/nonexistent/path/that/should/not/exist"),
10311047
true,
10321048
);
@@ -1062,7 +1078,7 @@ mod tests {
10621078
async fn local_echo_stdout() {
10631079
let (lang, code) = echo_hello_case();
10641080
let dir = temp_sandbox();
1065-
let cfg = LocalExecutionConfig::new(dir.clone(), true);
1081+
let cfg = LocalExecutionConfig::new(dir.clone(), dir.clone(), true);
10661082
let prov = LocalExecutionProvider::new(cfg).unwrap();
10671083
let h = prov
10681084
.create_session(SessionCreateRequest {
@@ -1093,7 +1109,7 @@ mod tests {
10931109
let sub = dir.join("pkg");
10941110
fs::create_dir_all(&sub).unwrap();
10951111
fs::write(sub.join("marker.txt"), "x").unwrap();
1096-
let cfg = LocalExecutionConfig::new(dir.clone(), true);
1112+
let cfg = LocalExecutionConfig::new(dir.clone(), dir.clone(), true);
10971113
let prov = LocalExecutionProvider::new(cfg).unwrap();
10981114
let h = prov
10991115
.create_session(SessionCreateRequest {
@@ -1119,7 +1135,7 @@ mod tests {
11191135
async fn timeout_returns_timeout_error() {
11201136
let (lang, code) = timeout_probe_case();
11211137
let dir = temp_sandbox();
1122-
let cfg = LocalExecutionConfig::new(dir.clone(), true);
1138+
let cfg = LocalExecutionConfig::new(dir.clone(), dir.clone(), true);
11231139
let prov = LocalExecutionProvider::new(cfg).unwrap();
11241140
let h = prov
11251141
.create_session(SessionCreateRequest {
@@ -1141,7 +1157,7 @@ mod tests {
11411157
async fn cancel_mid_run() {
11421158
let (lang, code) = long_running_case();
11431159
let dir = temp_sandbox();
1144-
let cfg = LocalExecutionConfig::new(dir.clone(), true);
1160+
let cfg = LocalExecutionConfig::new(dir.clone(), dir.clone(), true);
11451161
let prov = Arc::new(LocalExecutionProvider::new(cfg).unwrap());
11461162
let h = prov
11471163
.create_session(SessionCreateRequest {
@@ -1228,7 +1244,7 @@ mod tests {
12281244
#[test]
12291245
fn uv_env_key_changes_with_python_or_requirements() {
12301246
let dir = temp_sandbox();
1231-
let mut cfg1 = LocalExecutionConfig::new(dir.clone(), true);
1247+
let mut cfg1 = LocalExecutionConfig::new(dir.clone(), dir.clone(), true);
12321248
cfg1.python_runtime = LocalPythonRuntime::UvManaged;
12331249
cfg1.uv_python = "3.11".into();
12341250
cfg1.uv_requirements = vec!["numpy".into()];

0 commit comments

Comments
 (0)