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
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -euo pipefail
ENV="prod" # prod is another env, try taking it from github env
REPO="tilesprivacy/tiles"
# VERSION="${TILES_VERSION:-latest}"
VERSION="0.4.0-rc.1"
VERSION="0.4.0"
INSTALL_DIR="$HOME/.local/bin" # CLI install location
SERVER_DIR="$HOME/.local/lib/tiles/server" # Python server folder
MODELFILE_DIR="$HOME/.local/lib/tiles/modelfiles" # Python server folder
Expand Down
4 changes: 2 additions & 2 deletions server/stack/requirements/app-server/packages-app-server.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jinja2==3.1.6
markupsafe==3.0.3
mlx-lm==0.28.3
mypy-extensions==1.1.0
numpy==2.4.1
numpy==2.4.2
packaging==26.0
pathspec==1.0.4
platformdirs==4.5.1
Expand All @@ -31,7 +31,7 @@ requests==2.32.5
safetensors==0.7.0
starlette==0.48.0
tokenizers==0.22.2
tqdm==4.67.1
tqdm==4.67.3
transformers==4.57.6
typing-extensions==4.15.0
typing-inspection==0.4.2
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"lock_input_hash": "sha256:182c606e20dd957344cc3adc54391f47f4b6dd80b4481ddf219392a7aad6e0ce",
"lock_version": 1,
"locked_at": "2026-01-30T08:41:45.203370+00:00",
"locked_at": "2026-02-04T07:05:20.498851+00:00",
"other_inputs_hash": "sha256:63b3c2cfe2ec414938e81dace7aac779c7b902bae681618cd8827e9f16880985",
"requirements_hash": "sha256:288220847007f2f14c9a0aa2a972b33e92f6bb84f25dac1a248fbe6e55ec2bea",
"requirements_hash": "sha256:fa370cac93a65e09d769497457de2c60027eb53d6b7f05e44ff23e5a4a7f1b2e",
"version_inputs_hash": "sha256:58db986b7cd72eeded675f7c9afd8138fe024fb51451131b5562922bbde3cf43"
}
76 changes: 38 additions & 38 deletions server/stack/requirements/app-server/pylock.app-server.toml
Original file line number Diff line number Diff line change
Expand Up @@ -358,72 +358,72 @@ sha256 = "1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"

[[packages]]
name = "numpy"
version = "2.4.1"
version = "2.4.2"
index = "https://pypi.org/simple"

[[packages.wheels]]
url = "https://files.pythonhosted.org/packages/20/ca/857722353421a27f1465652b2c66813eeeccea9d76d5f7b74b99f298e60e/numpy-2.4.1-cp313-cp313-macosx_11_0_arm64.whl"
upload-time = 2026-01-10T06:43:09Z
size = 12368657
url = "https://files.pythonhosted.org/packages/09/f0/817d03a03f93ba9c6c8993de509277d84e69f9453601915e4a69554102a1/numpy-2.4.2-cp313-cp313-macosx_11_0_arm64.whl"
upload-time = 2026-01-31T23:11:19Z
size = 14688322

[packages.wheels.hashes]
sha256 = "82c55962006156aeef1629b953fd359064aa47e4d82cfc8e67f0918f7da3344f"
sha256 = "bd3a7a9f5847d2fb8c2c6d1c862fa109c31a9abeca1a3c2bd5a64572955b2979"

[[packages.wheels]]
url = "https://files.pythonhosted.org/packages/81/0d/2377c917513449cc6240031a79d30eb9a163d32a91e79e0da47c43f2c0c8/numpy-2.4.1-cp313-cp313-macosx_14_0_arm64.whl"
upload-time = 2026-01-10T06:43:13Z
size = 5197256
url = "https://files.pythonhosted.org/packages/da/b4/f805ab79293c728b9a99438775ce51885fd4f31b76178767cfc718701a39/numpy-2.4.2-cp313-cp313-macosx_14_0_arm64.whl"
upload-time = 2026-01-31T23:11:22Z
size = 5198157

[packages.wheels.hashes]
sha256 = "71abbea030f2cfc3092a0ff9f8c8fdefdc5e0bf7d9d9c99663538bb0ecdac0b9"
sha256 = "8e4549f8a3c6d13d55041925e912bfd834285ef1dd64d6bc7d542583355e2e98"

[[packages.wheels]]
url = "https://files.pythonhosted.org/packages/ba/87/d341e519956273b39d8d47969dd1eaa1af740615394fe67d06f1efa68773/numpy-2.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl"
upload-time = 2026-01-10T06:43:19Z
size = 16359305
url = "https://files.pythonhosted.org/packages/04/dc/46066ce18d01645541f0186877377b9371b8fa8017fa8262002b4ef22612/numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl"
upload-time = 2026-01-31T23:11:28Z
size = 16607311

[packages.wheels.hashes]
sha256 = "d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8"
sha256 = "d0d9b7c93578baafcbc5f0b83eaf17b79d345c6f36917ba0c67f45226911d499"

[[packages.wheels]]
url = "https://files.pythonhosted.org/packages/cf/b8/090b8bd27b82a844bb22ff8fdf7935cb1980b48d6e439ae116f53cdc2143/numpy-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl"
upload-time = 2026-01-10T06:43:23Z
size = 18284380
url = "https://files.pythonhosted.org/packages/b7/20/adb6e6adde6d0130046e6fdfb7675cc62bc2f6b7b02239a09eb58435753d/numpy-2.4.2-cp313-cp313-musllinux_1_2_x86_64.whl"
upload-time = 2026-01-31T23:11:33Z
size = 18334210

[packages.wheels.hashes]
sha256 = "79e9e06c4c2379db47f3f6fc7a8652e7498251789bf8ff5bd43bf478ef314ca2"
sha256 = "c7ac672d699bf36275c035e16b65539931347d68b70667d28984c9fb34e07fa7"

[[packages.wheels]]
url = "https://files.pythonhosted.org/packages/da/a1/354583ac5c4caa566de6ddfbc42744409b515039e085fab6e0ff942e0df5/numpy-2.4.1-cp313-cp313t-macosx_11_0_arm64.whl"
upload-time = 2026-01-10T06:43:34Z
size = 12496156
url = "https://files.pythonhosted.org/packages/25/a1/9510aa43555b44781968935c7548a8926274f815de42ad3997e9e83680dd/numpy-2.4.2-cp313-cp313t-macosx_11_0_arm64.whl"
upload-time = 2026-01-31T23:11:42Z
size = 14815866

[packages.wheels.hashes]
sha256 = "f93bc6892fe7b0663e5ffa83b61aab510aacffd58c16e012bb9352d489d90cb7"
sha256 = "5633c0da313330fd20c484c78cdd3f9b175b55e1a766c4a174230c6b70ad8262"

[[packages.wheels]]
url = "https://files.pythonhosted.org/packages/51/b0/42807c6e8cce58c00127b1dc24d365305189991f2a7917aa694a109c8d7d/numpy-2.4.1-cp313-cp313t-macosx_14_0_arm64.whl"
upload-time = 2026-01-10T06:43:36Z
size = 5324663
url = "https://files.pythonhosted.org/packages/36/30/6bbb5e76631a5ae46e7923dd16ca9d3f1c93cfa8d4ed79a129814a9d8db3/numpy-2.4.2-cp313-cp313t-macosx_14_0_arm64.whl"
upload-time = 2026-01-31T23:11:44Z
size = 5325631

[packages.wheels.hashes]
sha256 = "178de8f87948163d98a4c9ab5bee4ce6519ca918926ec8df195af582de28544d"
sha256 = "d9f64d786b3b1dd742c946c42d15b07497ed14af1a1f3ce840cce27daa0ce913"

[[packages.wheels]]
url = "https://files.pythonhosted.org/packages/03/d1/8cf62d8bb2062da4fb82dd5d49e47c923f9c0738032f054e0a75342faba7/numpy-2.4.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl"
upload-time = 2026-01-10T06:43:41Z
size = 16407279
url = "https://files.pythonhosted.org/packages/ea/5c/08887c54e68e1e28df53709f1893ce92932cc6f01f7c3d4dc952f61ffd4e/numpy-2.4.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl"
upload-time = 2026-01-31T23:11:50Z
size = 16655398

[packages.wheels.hashes]
sha256 = "529050522e983e00a6c1c6b67411083630de8b57f65e853d7b03d9281b8694d2"
sha256 = "2fb882da679409066b4603579619341c6d6898fc83a8995199d5249f986e8e8f"

[[packages.wheels]]
url = "https://files.pythonhosted.org/packages/30/b4/e7f5ff8697274c9d0fa82398b6a372a27e5cef069b37df6355ccb1f1db1a/numpy-2.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl"
upload-time = 2026-01-10T06:43:46Z
size = 18329884
url = "https://files.pythonhosted.org/packages/2a/d5/cbade46ce97c59c6c3da525e8d95b7abe8a42974a1dc5c1d489c10433e88/numpy-2.4.2-cp313-cp313t-musllinux_1_2_x86_64.whl"
upload-time = 2026-01-31T23:11:55Z
size = 18379680

[packages.wheels.hashes]
sha256 = "9171a42fcad32dcf3fa86f0a4faa5e9f8facefdb276f54b8b390d90447cff4e2"
sha256 = "0f01dcf33e73d80bd8dc0f20a71303abbafa26a19e23f6b68d1aa9990af90257"

[[packages]]
name = "packaging"
Expand Down Expand Up @@ -756,16 +756,16 @@ sha256 = "38337540fbbddff8e999d59970f3c6f35a82de10053206a7562f1ea02d046fa5"

[[packages]]
name = "tqdm"
version = "4.67.1"
version = "4.67.3"
index = "https://pypi.org/simple"

[[packages.wheels]]
url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl"
upload-time = 2024-11-24T20:12:19Z
size = 78540
url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl"
upload-time = 2026-02-03T17:35:50Z
size = 78374

[packages.wheels.hashes]
sha256 = "26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"
sha256 = "ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf"

[[packages]]
name = "transformers"
Expand Down
5 changes: 4 additions & 1 deletion tiles/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tiles"
version = "0.4.0-rc.1"
version = "0.4.0"
edition = "2024"

[dependencies]
Expand All @@ -15,3 +15,6 @@ owo-colors = "4"
futures-util = "0.3"
hf-hub = {version = "0.4", features = ["tokio"]}
rustyline = "17.0"

[dev-dependencies]
tempfile = "3"
2 changes: 1 addition & 1 deletion tiles/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use tiles::runtime::{RunArgs, build_runtime};
mod commands;
#[derive(Debug, Parser)]
#[command(name = "tiles")]
#[command(version, about = "Your private AI assistant with offline memory.", long_about = None)]
#[command(version, about = "Your private and secure AI assistant for everyday use.", long_about = None, after_help = "Documentation: https://tiles.run/book\nReport issues: https://github.com/tilesprivacy/tiles/issues")]
struct Cli {
#[command(subcommand)]
command: Commands,
Expand Down
107 changes: 29 additions & 78 deletions tiles/src/runtime/mlx.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::runtime::RunArgs;
use crate::utils::config::{
create_default_memory_folder, get_config_dir, get_default_memory_path, get_lib_dir,
ConfigProvider, DefaultProvider, create_default_memory_folder, get_default_memory_path,
get_memory_path, set_memory_path,
};
use crate::utils::hf_model_downloader::*;
Expand Down Expand Up @@ -100,8 +100,8 @@ impl MLXRuntime {
return Ok(());
}

let config_dir = get_config_dir()?;
let mut server_dir = get_lib_dir()?;
let config_dir = DefaultProvider.get_config_dir()?;
let mut server_dir = DefaultProvider.get_lib_dir()?;
let pid_file = config_dir.join("server.pid");
fs::create_dir_all(&config_dir).context("Failed to create config directory")?;
server_dir = server_dir.join("server");
Expand Down Expand Up @@ -129,7 +129,7 @@ impl MLXRuntime {
println!("Server is not running");
return Ok(());
}
let pid_file = get_config_dir()?.join("server.pid");
let pid_file = DefaultProvider.get_config_dir()?.join("server.pid");

if !pid_file.exists() {
eprintln!("server pid doesnt exist");
Expand All @@ -144,70 +144,14 @@ impl MLXRuntime {
}
}

#[allow(dead_code)]
fn run_model_by_sub_process(modelfile: Modelfile) {
// build the arg list from modelfile
let mut args: Vec<String> = vec![];
args.push("--model".to_owned());
args.push(modelfile.from.unwrap());
for parameter in modelfile.parameters {
let param_value = parameter.value.to_string();
match parameter.param_type.as_str() {
"num_predict" => {
args.push("--max-tokens".to_owned());
args.push(param_value);
}
"temperature" => {
args.push("--temp".to_owned());
args.push(param_value);
}
"top_p" => {
args.push("--top-p".to_owned());
args.push(param_value);
}
"seed" => {
args.push("--seed".to_owned());
args.push(param_value);
}
_ => {}
}
}
if let Some(system_prompt) = modelfile.system {
args.push("--system-prompt".to_owned());
args.push(system_prompt);
}
if let Some(adapter_path) = modelfile.adapter {
args.push("--adapter-path".to_owned());
args.push(adapter_path);
}
let mut mlx = match Command::new("mlx_lm.chat").args(args).spawn() {
Ok(child) => child,
Err(e) => {
if e.kind() == std::io::ErrorKind::NotFound {
eprintln!("❌ Error: mlx_lm.chat command not found");
eprintln!("💡 Hint: Install mlx-lm by running: pip install mlx-lm");
eprintln!("📝 Note: mlx-lm is only available on macOS with Apple Silicon");
std::process::exit(1);
} else {
eprintln!("❌ Error: Failed to spawn mlx_lm.chat: {}", e);
std::process::exit(1);
}
}
};

if let Err(err) = mlx.wait() {
eprintln!("❌ Error: Failed to wait for mlx_lm: {}", err);
}
}

struct TilesHinter;

impl Hinter for TilesHinter {
type Hint = String;

fn hint(&self, line: &str, _pos: usize, _ctx: &rustyline::Context<'_>) -> Option<Self::Hint> {
if line.is_empty() {
Some("Send a message (/? for help)".to_string())
Some("Send a message (/help for help)".to_string())
} else {
None
}
Expand Down Expand Up @@ -260,20 +204,22 @@ fn handle_slash_command(input: &str, modelname: &str) -> SlashCommand {
}

fn show_help(model_name: &str) {
println!("\n=== Tiles REPL Help ===\n");
println!("\n=== Tiles REPL ===\n");

println!("Model:");
println!(" {}", model_name);

println!("Directory:");
println!(" {}\n", get_memory_path().unwrap());

Comment on lines 206 to 214
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's explore the repository structure
git ls-files | head -20

Repository: tilesprivacy/tiles

Length of output: 351


🏁 Script executed:

# Check if the file exists
ls -la tiles/src/runtime/mlx.rs

Repository: tilesprivacy/tiles

Length of output: 136


🏁 Script executed:

# Read the specific lines mentioned in the review
sed -n '206,214p' tiles/src/runtime/mlx.rs

Repository: tilesprivacy/tiles

Length of output: 275


🏁 Script executed:

# Let's see more context around those lines
sed -n '200,220p' tiles/src/runtime/mlx.rs

Repository: tilesprivacy/tiles

Length of output: 551


🏁 Script executed:

# Find the get_memory_path function definition
rg "fn get_memory_path" -A 5

Repository: tilesprivacy/tiles

Length of output: 544


🏁 Script executed:

# Also search for get_default_memory_path to see if it exists
rg "get_default_memory_path"

Repository: tilesprivacy/tiles

Length of output: 522


🏁 Script executed:

# Search for all calls to get_memory_path to understand usage patterns
rg "get_memory_path\(\)" -B 2 -A 2

Repository: tilesprivacy/tiles

Length of output: 1085


🏁 Script executed:

# Get the full implementation of get_memory_path
sed -n '/^pub fn get_memory_path/,/^}/p' tiles/src/utils/config.rs | head -30

Repository: tilesprivacy/tiles

Length of output: 593


🏁 Script executed:

# Get the full implementation of get_default_memory_path
sed -n '/^pub fn get_default_memory_path/,/^}/p' tiles/src/utils/config.rs | head -30

Repository: tilesprivacy/tiles

Length of output: 248


🏁 Script executed:

# Check get_or_set_memory_path to see how it handles errors
sed -n '/^fn get_or_set_memory_path/,/^}/p' tiles/src/runtime/mlx.rs | head -40

Repository: tilesprivacy/tiles

Length of output: 1814


🏁 Script executed:

# Check what Result type is being used (custom Result or std::Result)
rg "^type Result" tiles/src/utils/config.rs

Repository: tilesprivacy/tiles

Length of output: 44


🏁 Script executed:

# Look at the beginning of config.rs to see what Result is
head -30 tiles/src/utils/config.rs

Repository: tilesprivacy/tiles

Length of output: 1018


Handle error gracefully in show_help() instead of panicking.

get_memory_path() returns Result<String> and can fail when memory path isn't configured, causing unwrap() to panic the REPL. Replace with error handling using get_default_memory_path() as a fallback, or display "" instead.

🛠️ Proposed fix
-    println!("  {}\n", get_memory_path().unwrap());
+    let mem_path = match get_memory_path() {
+        Ok(p) => p,
+        Err(_) => get_default_memory_path()
+            .map(|p| p.display().to_string())
+            .unwrap_or_else(|_| "<not configured>".to_string()),
+    };
+    println!("  {}\n", mem_path);
🤖 Prompt for AI Agents
In `@tiles/src/runtime/mlx.rs` around lines 206 - 214, The show_help() function
currently calls get_memory_path().unwrap(), which can panic; change it to handle
the Result: call get_memory_path() and if Ok(path) print it, otherwise call
get_default_memory_path() and use that when available, or print "<not
configured>" as the fallback; update the print block in show_help() to use this
non-panicking value so the REPL no longer crashes when memory path is missing.

println!("Available Commands:");
println!(" /? Show this help message");
println!(" /help Show this help message");
println!(" /bye Exit the REPL");
println!();

println!("Current Model:");
println!(" {}", model_name);
println!();
println!("\nDocumentation: https://tiles.run/book");

println!("Usage Tips:");
println!(" - Type your questions or prompts directly");
println!("Report issues: https://github.com/tilesprivacy/tiles/issues");
println!();
}

Expand Down Expand Up @@ -542,12 +488,12 @@ async fn chat(
"python_code": python_code,
"messages": [{"role": "assistant", "content": g_reply}, {"role": "user", "content": input}]
});
let res = client
.post("http://127.0.0.1:6969/v1/responses")
.json(&body)
.send()
.await
.unwrap();
let api_url = if run_args.memory {
"http://127.0.0.1:6969/v1/chat/completions"
} else {
"http://127.0.0.1:6969/v1/responses"
};
let res = client.post(api_url).json(&body).send().await.unwrap();
Comment on lines +491 to +496
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cd tiles && find . -name "mlx.rs" -type f

Repository: tilesprivacy/tiles

Length of output: 82


🏁 Script executed:

wc -l tiles/src/runtime/mlx.rs

Repository: tilesprivacy/tiles

Length of output: 90


🏁 Script executed:

sed -n '480,510p' tiles/src/runtime/mlx.rs

Repository: tilesprivacy/tiles

Length of output: 1077


🏁 Script executed:

sed -n '470,490p' tiles/src/runtime/mlx.rs

Repository: tilesprivacy/tiles

Length of output: 559


🏁 Script executed:

sed -n '500,530p' tiles/src/runtime/mlx.rs

Repository: tilesprivacy/tiles

Length of output: 1196


🏁 Script executed:

sed -n '491,496p' tiles/src/runtime/mlx.rs

Repository: tilesprivacy/tiles

Length of output: 287


Propagate HTTP request errors instead of panicking with unwrap().

The client.post(api_url).send().await.unwrap() call will panic on network failures. Since the function returns Result<ChatResponse, String>, errors should be propagated to allow the REPL to recover.

🛠️ Suggested fix
-    let res = client.post(api_url).json(&body).send().await.unwrap();
+    let res = client
+        .post(api_url)
+        .json(&body)
+        .send()
+        .await
+        .map_err(|e| e.to_string())?;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let api_url = if run_args.memory {
"http://127.0.0.1:6969/v1/chat/completions"
} else {
"http://127.0.0.1:6969/v1/responses"
};
let res = client.post(api_url).json(&body).send().await.unwrap();
let api_url = if run_args.memory {
"http://127.0.0.1:6969/v1/chat/completions"
} else {
"http://127.0.0.1:6969/v1/responses"
};
let res = client
.post(api_url)
.json(&body)
.send()
.await
.map_err(|e| e.to_string())?;
🤖 Prompt for AI Agents
In `@tiles/src/runtime/mlx.rs` around lines 491 - 496, The HTTP POST currently
uses client.post(api_url).json(&body).send().await.unwrap(), which will panic on
failures; change this to propagate errors into the function's Result by
replacing the unwrap with error mapping/propagation (e.g., await the send and
use ? or map_err to convert reqwest errors into the function's String error
type), and likewise handle non-success HTTP statuses before parsing the response
into ChatResponse; update the variables referenced (api_url, run_args.memory,
and res) so send errors and bad-status responses return Err(String) instead of
panicking.


let mut stream = res.bytes_stream();
let mut accumulated = String::new();
Expand All @@ -574,12 +520,17 @@ async fn chat(

// Parse JSON
let v: Value = serde_json::from_str(data).unwrap();
// println!("{:?}", v);
// Check for metrics in the response
if let Some(metrics_obj) = v.get("metrics") {
metrics = serde_json::from_value(metrics_obj.clone()).ok();
}
if let Some(delta) = v["output"][0]["content"][0]["text"].as_str() {
let model_text: Option<&str> = if run_args.memory {
v["choices"][0]["delta"]["content"].as_str()
} else {
v["output"][0]["content"][0]["text"].as_str()
};

if let Some(delta) = model_text {
accumulated.push_str(delta);
if !run_args.memory && delta.contains("**[Answer]**") {
is_answer_start = true;
Expand Down Expand Up @@ -648,10 +599,10 @@ async fn wait_until_server_is_up() {

fn get_default_modelfile(memory_mode: bool) -> Result<PathBuf> {
if memory_mode {
let path = get_lib_dir()?.join("modelfiles/mem-agent");
let path = DefaultProvider.get_lib_dir()?.join("modelfiles/mem-agent");
Ok(path)
} else {
let path = get_lib_dir()?.join("modelfiles/gpt-oss");
let path = DefaultProvider.get_lib_dir()?.join("modelfiles/gpt-oss");
Ok(path)
}
}
Loading