Skip to content

Commit 66c2875

Browse files
author
Chris Warren-Smith
committed
LLAMA: nitro added mkdir tool
1 parent 802e78e commit 66c2875

1 file changed

Lines changed: 29 additions & 12 deletions

File tree

llama/nitro.cpp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,21 @@ static bool write_file(const std::string &path, const std::string &data) {
643643
return f.good();
644644
}
645645

646+
static bool make_dir(const std::string &path) {
647+
try {
648+
std::filesystem::path p(path);
649+
if (fs::exists(p)) {
650+
return true;
651+
}
652+
std::error_code ec;
653+
return fs::create_directories(p, ec);
654+
}
655+
catch (const std::filesystem::filesystem_error &e) {
656+
log_write("mkdir failed [%s]", e.what());
657+
return false;
658+
}
659+
}
660+
646661
//
647662
// System prompt
648663
//
@@ -659,6 +674,7 @@ static std::string build_system_prompt(const std::vector<std::string> &knowledge
659674
" TOOL:LIST [dir] list files (default: sandbox root)\n"
660675
" TOOL:READ <file> read file contents\n"
661676
" TOOL:WRITE <file> <text> write text to file\n"
677+
" TOOL:MKDIR <dir> create a subfolder inside the sandbox\n"
662678
" TOOL:EXISTS <file> YES or NO\n"
663679
" TOOL:RUN <prog> [args] run program inside sandbox\n"
664680
" TOOL:DATE current date\n"
@@ -1768,7 +1784,7 @@ std::string AgentState::process_tool(const std::string &cmd, const NitroConfig &
17681784
const std::vector<std::string> &run_allowed = cfg.run_allowed;
17691785

17701786
std::string op, arg1, arg2;
1771-
auto sp1 = cmd.find(' ');
1787+
auto sp1 = cmd.find_first_of(" \n");
17721788
if (sp1 == std::string::npos) {
17731789
op = trim(cmd);
17741790
} else {
@@ -1839,32 +1855,33 @@ std::string AgentState::process_tool(const std::string &cmd, const NitroConfig &
18391855
if (!tui.confirm_dialog(std::format("Allow model to write {}?", p))) {
18401856
return "ERROR: action prevented by user";
18411857
}
1842-
std::string content = disclose(strip_code_fences(arg1, arg2), '`', '`');
1858+
std::string content = disclose(disclose(strip_code_fences(arg1, arg2), '`', '`'), '"', '"');
18431859
return write_file(p, content) ? "OK: written to " + arg1 : "ERROR: write failed for " + arg1;
18441860
}
1861+
if (op == "TOOL:MKDIR") {
1862+
std::string p = resolve(arg1);
1863+
if (!path_in_sandbox(sandbox, p)) {
1864+
return "ERROR: path outside sandbox";
1865+
}
1866+
return make_dir(p) ? "OK: created " + arg1 : "ERROR: mkdir failed for " + arg1;
1867+
}
18451868
if (op == "TOOL:CURL") {
18461869
return tool_curl(arg1);
18471870
}
18481871
if (op == "TOOL:INTROSPECT") {
18491872
return introspect(cfg);
18501873
}
18511874
if (op == "TOOL:RUN") {
1852-
std::string prog = resolve(arg1);
1853-
if (!path_in_sandbox(sandbox, prog)) {
1854-
return "ERROR: path outside sandbox";
1855-
}
18561875
if (!run_allowed.empty()) {
1857-
std::string basename = fs::path(prog).filename().string();
1858-
bool permitted = ranges::any_of(run_allowed,
1859-
[&](const std::string &a){ return a == basename; });
1876+
bool permitted = ranges::any_of(run_allowed, [&](const std::string &a) {return a == arg1;});
18601877
if (!permitted) {
1861-
return "ERROR: '" + basename + "' is not in the TOOL:RUN allowlist. "
1878+
return "ERROR: '" + arg1 + "' is not in the TOOL:RUN allowlist. "
18621879
"Use /set run_allowed <name> to permit it.";
18631880
}
1864-
} else if (!tui.confirm_dialog(std::format("Allow {} to run?", prog))) {
1881+
} else if (!tui.confirm_dialog(std::format("Allow {} {} to run?", arg1, arg2))) {
18651882
return "ERROR: prevented by user";
18661883
}
1867-
std::string command = prog + " " + arg2 + " 2>&1";
1884+
std::string command = arg1 + " " + arg2 + " 2>&1";
18681885
FILE *fp = popen(command.c_str(), "r");
18691886
if (!fp) {
18701887
return "ERROR: popen failed";

0 commit comments

Comments
 (0)