Skip to content

Commit 3bb3b10

Browse files
committed
refactor: Move all data files in data directory, docker support updated
1 parent 7c49b2f commit 3bb3b10

File tree

9 files changed

+70
-24
lines changed

9 files changed

+70
-24
lines changed

.dockerignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
/target/*
1+
/target/*
2+
/data/*

.gitignore

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
debug/
22
target/
3-
logs/
3+
data/
44
.vscode/
55
**/*.rs.bk
66
*.pdb
7-
history.json
87
huly-coder-local.yaml
9-
/memory.yaml
10-
/.fastembed_cache/
11-
openrouter_models.json
8+
/.fastembed_cache/

README.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,19 @@ cargo run
4646
To build the Huly Coder image, run:
4747

4848
```bash
49-
docker build -t huly-coder -f "./Dockerfile" .
49+
cargo xtask build-docker
5050
```
5151

5252
### Running Huly Coder
5353

5454
To run the Huly Coder image:
5555

56+
Create a `huly-coder-local.yaml` file in your `data` directory with overrided configurations and run the following command:
57+
5658
```bash
57-
docker run -it --rm -v "$(pwd)/target/workspace:/target/workspace" -e OPENROUTER_API_KEY=<your-api-key> huly-coder
59+
cargo xtask run-docker <data_dir> <workspace_dir>
5860
```
5961

60-
Replace `<your-api-key>` with your OpenRouter API key.
61-
62-
The agent uses `target/workspace` as its working directory.
63-
6462
## Available Tools
6563

6664
Huly Coder comes with a comprehensive set of tools:

src/agent/utils.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use tokio::sync::RwLock;
1313
use crate::templates::{ENV_DETAILS, SYSTEM_PROMPT};
1414
use crate::tools::execute_command::ProcessRegistry;
1515
use crate::tools::memory::Entity;
16+
use crate::HISTORY_PATH;
1617

1718
pub const MAX_FILES: usize = 10000;
1819

@@ -142,7 +143,7 @@ pub fn is_last_user_message(messages: &[Message]) -> bool {
142143

143144
pub fn persist_history(messages: &[Message]) {
144145
fs::write(
145-
"history.json",
146+
HISTORY_PATH,
146147
serde_json::to_string_pretty(messages).unwrap(),
147148
)
148149
.unwrap();

src/config.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use serde::Deserialize;
77

88
const CONFIG_FILE: &str = "huly-coder.yaml";
99
const LOCAL_CONFIG_FILE: &str = "huly-coder-local.yaml";
10+
const DOCKER_LOCAL_CONFIG_FILE: &str = "data/huly-coder-local.yaml";
1011

1112
#[derive(Debug, Deserialize, Clone)]
1213
pub enum ProviderKind {
@@ -90,6 +91,12 @@ impl Config {
9091
builder = builder.add_source(config::File::with_name(LOCAL_CONFIG_FILE));
9192
}
9293

94+
// Docker related local config file that stored in /data directory
95+
if Path::new(DOCKER_LOCAL_CONFIG_FILE).exists() {
96+
tracing::info!("Found local config at {}", DOCKER_LOCAL_CONFIG_FILE);
97+
builder = builder.add_source(config::File::with_name(DOCKER_LOCAL_CONFIG_FILE));
98+
}
99+
93100
let user_config = format!(
94101
"{}/{}",
95102
dirs::home_dir().unwrap().to_str().unwrap(),

src/main.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ pub mod templates;
2929
pub mod tools;
3030
mod tui;
3131

32+
const HISTORY_PATH: &str = "data/history.json";
33+
3234
#[derive(Parser, Debug)]
3335
#[command(version, about, long_about = None)]
3436
struct Args {
@@ -38,7 +40,7 @@ struct Args {
3840
}
3941

4042
fn init_logger() {
41-
let writer = tracing_appender::rolling::daily("logs", "huly-coder.log");
43+
let writer = tracing_appender::rolling::daily("data/logs", "huly-coder.log");
4244
tracing_subscriber::registry()
4345
.with(
4446
tracing_subscriber::fmt::layer()
@@ -102,8 +104,8 @@ async fn main() -> color_eyre::Result<()> {
102104
tokio::sync::mpsc::unbounded_channel::<AgentOutputEvent>();
103105
let (control_sender, control_receiver) =
104106
tokio::sync::mpsc::unbounded_channel::<AgentControlEvent>();
105-
let history = if !args.skip_load_messages && std::path::Path::new("history.json").exists() {
106-
serde_json::from_str(&std::fs::read_to_string("history.json").unwrap()).unwrap()
107+
let history = if !args.skip_load_messages && std::path::Path::new(HISTORY_PATH).exists() {
108+
serde_json::from_str(&std::fs::read_to_string(HISTORY_PATH).unwrap()).unwrap()
107109
} else {
108110
Vec::new()
109111
};

src/providers/model_info.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use serde::Deserialize;
66

77
use crate::config::Config;
88

9-
const OPENROUTER_MODELS_FILE: &str = "openrouter_models.json";
9+
const OPENROUTER_MODELS_FILE: &str = "data/openrouter_models.json";
1010
const ANTHROPIC_MODELS: &str = include_str!("anthropic_models.json");
1111
const OPENAI_MODELS: &str = include_str!("openai_models.json");
1212

src/tools/memory/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use super::AgentToolError;
1919
mod tests;
2020

2121
const TOOLS_STR: &str = include_str!("tools.json");
22-
const MEMORY_PATH: &str = "memory.yaml";
22+
const MEMORY_PATH: &str = "data/memory.yaml";
2323

2424
#[derive(Clone, Deserialize)]
2525
struct JsonToolDefinition {

xtask/src/main.rs

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ fn try_main() -> Result<(), DynError> {
1818
match task.as_deref() {
1919
Some("clean") => clean()?,
2020
Some("dist") => dist()?,
21+
Some("build-docker") => build_docker()?,
22+
Some("run-docker") => {
23+
let Some(data_dir) = env::args().nth(2) else {
24+
eprintln!("data_dir is required");
25+
std::process::exit(-1);
26+
};
27+
let Some(workspace_dir) = env::args().nth(3) else {
28+
eprintln!("workspace_dir is required");
29+
std::process::exit(-1);
30+
};
31+
run_docker(&data_dir, &workspace_dir)?;
32+
}
2133
_ => print_help(),
2234
}
2335
Ok(())
@@ -27,19 +39,18 @@ fn print_help() {
2739
eprintln!(
2840
"Tasks:
2941
30-
clean cleans project directory from logs and artifacts
31-
dist builds application
42+
clean cleans project directory from logs and artifacts
43+
dist builds application
44+
build-docker builds docker image
45+
run-docker <data_dir> <workspace_dir> runs docker image
3246
"
3347
)
3448
}
3549

3650
fn clean() -> Result<(), DynError> {
37-
let _ = fs::remove_dir_all(project_root().join("logs"));
51+
let _ = fs::remove_dir_all(project_root().join("data"));
3852
let _ = fs::remove_dir_all(project_root().join(".fastembed_cache"));
3953
let _ = fs::remove_dir_all(project_root().join("target/workspace"));
40-
let _ = fs::remove_file(project_root().join("memory.yaml"));
41-
let _ = fs::remove_file(project_root().join("history.json"));
42-
let _ = fs::remove_file(project_root().join("openrouter_models.json"));
4354
Ok(())
4455
}
4556

@@ -85,6 +96,35 @@ fn dist_binary() -> Result<(), DynError> {
8596
Ok(())
8697
}
8798

99+
fn build_docker() -> Result<(), DynError> {
100+
let _ = Command::new("docker")
101+
.arg("build")
102+
.arg("-t")
103+
.arg("huly-coder")
104+
.arg("-f")
105+
.arg("./Dockerfile")
106+
.arg(".")
107+
.status()?;
108+
Ok(())
109+
}
110+
111+
fn run_docker(data_dir: &str, workspace_dir: &str) -> Result<(), DynError> {
112+
let _ = Command::new("docker")
113+
.arg("run")
114+
.arg("-it")
115+
.arg("--rm")
116+
.arg("-v")
117+
.arg(format!("{}:/target/workspace", workspace_dir))
118+
.arg("-v")
119+
.arg(format!("{}:/data", data_dir))
120+
.arg("-v")
121+
.arg(format!("{}/.fastembed_cache:/.fastembed_cache", data_dir))
122+
.arg("huly-coder")
123+
.status()?;
124+
125+
Ok(())
126+
}
127+
88128
fn project_root() -> PathBuf {
89129
Path::new(&env!("CARGO_MANIFEST_DIR"))
90130
.ancestors()

0 commit comments

Comments
 (0)