@@ -70,11 +70,8 @@ static bool write_file(const std::string &path, const std::string &data)
7070static std::string list_dir (const std::string &path);
7171static bool path_in_sandbox (const std::string &sandbox, const std::string &path);
7272static std::string strip_code_fences (const std::string &filename, const std::string &src);
73- static std::string process_tool (const std::string &line, const std::string &sandbox,
74- const std::vector<std::string> &run_allowed,
75- TuiState &tui);
76- static std::string build_system_prompt (const std::vector<std::string> &knowledge_files,
77- const std::string &sandbox);
73+ static std::string process_tool (const std::string &line, const NitroConfig &cfg, TuiState &tui);
74+ static std::string build_system_prompt (const std::vector<std::string> &knowledge_files, const std::string &sandbox);
7875
7976// ─── RAG indexing ─────────────────────────────────────────────────────────────
8077static constexpr int BATCH_SIZE = 512 ;
@@ -388,6 +385,41 @@ static std::string json_escape(const std::string &s) {
388385 return out;
389386}
390387
388+ static std::string introspect (const NitroConfig &cfg) {
389+ static constexpr std::string_view tmpl =
390+ " {{\n "
391+ " \" model_path\" : \" {}\" ,\n "
392+ " \" embed_path\" : \" {}\" ,\n "
393+ " \" sandbox\" : \" {}\" ,\n "
394+ " \" n_ctx\" : {},\n "
395+ " \" n_batch\" : {},\n "
396+ " \" n_gpu_layers\" : {},\n "
397+ " \" n_max_tokens\" : {},\n "
398+ " \" temperature\" : {},\n "
399+ " \" top_p\" : {},\n "
400+ " \" min_p\" : {},\n "
401+ " \" top_k\" : {},\n "
402+ " \" penalty_repeat\" : {},\n "
403+ " \" penalty_last_n\" : {},\n "
404+ " \" rag_top_k\" : {}\n "
405+ " }}\n " ;
406+ return std::format (tmpl,
407+ cfg.model_path ,
408+ cfg.embed_path ,
409+ cfg.sandbox ,
410+ cfg.n_ctx ,
411+ cfg.n_batch ,
412+ cfg.n_gpu_layers ,
413+ cfg.n_max_tokens ,
414+ cfg.temperature ,
415+ cfg.top_p ,
416+ cfg.min_p ,
417+ cfg.top_k ,
418+ cfg.penalty_repeat ,
419+ cfg.penalty_last_n ,
420+ cfg.rag_top_k );
421+ }
422+
391423// Persist the current cfg to ~/.config/nitro.settings.json.
392424static bool save_settings (const NitroConfig &cfg) {
393425 std::string path = settings_path ();
@@ -397,24 +429,11 @@ static bool save_settings(const NitroConfig &cfg) {
397429 fs::create_directories (dir, ec);
398430
399431 std::ofstream f (path, std::ios::trunc);
400- if (!f) return false ;
432+ if (!f) {
433+ return false ;
434+ }
401435
402- f << " {\n " ;
403- f << " \" model_path\" : \" " << json_escape (cfg.model_path ) << " \" ,\n " ;
404- f << " \" embed_path\" : \" " << json_escape (cfg.embed_path ) << " \" ,\n " ;
405- f << " \" sandbox\" : \" " << json_escape (cfg.sandbox ) << " \" ,\n " ;
406- f << " \" n_ctx\" : " << cfg.n_ctx << " ,\n " ;
407- f << " \" n_batch\" : " << cfg.n_batch << " ,\n " ;
408- f << " \" n_gpu_layers\" : " << cfg.n_gpu_layers << " ,\n " ;
409- f << " \" n_max_tokens\" : " << cfg.n_max_tokens << " ,\n " ;
410- f << " \" temperature\" : " << cfg.temperature << " ,\n " ;
411- f << " \" top_p\" : " << cfg.top_p << " ,\n " ;
412- f << " \" min_p\" : " << cfg.min_p << " ,\n " ;
413- f << " \" top_k\" : " << cfg.top_k << " ,\n " ;
414- f << " \" penalty_repeat\" : " << cfg.penalty_repeat << " ,\n " ;
415- f << " \" penalty_last_n\" : " << cfg.penalty_last_n << " ,\n " ;
416- f << " \" rag_top_k\" : " << cfg.rag_top_k << " \n " ;
417- f << " }\n " ;
436+ f << introspect (cfg);
418437
419438 return f.good ();
420439}
@@ -1195,6 +1214,7 @@ struct AgentState {
11951214 std::string memory_info_text ();
11961215 float tokens_per_sec () const ;
11971216};
1217+
11981218void AgentState::apply_generation_params (const NitroConfig &cfg) {
11991219 llama->add_stop (" <|turn|>" );
12001220 llama->add_stop (" <|im_end|>" );
@@ -1461,7 +1481,7 @@ bool AgentState::run_turn(const std::string &user_message,
14611481 tui.append_line (" [tool] " + op + " " + arg1 +
14621482 (op == " TOOL:WRITE" ? " <content>" : " " ));
14631483 tui.redraw_all ();
1464- std::string result = process_tool (tool_line, cfg. sandbox , cfg. run_allowed , tui);
1484+ std::string result = process_tool (tool_line, cfg, tui);
14651485 tui.append_line (" [tool] → " +
14661486 result.substr (0 , 200 ) + (result.size () > 200 ? " …" : " " ));
14671487 tui.redraw_all ();
@@ -1486,7 +1506,7 @@ bool AgentState::run_turn(const std::string &user_message,
14861506 std::string trimmed = buffer;
14871507 trimmed.erase (0 , trimmed.find_first_not_of (" \t " ));
14881508 if (trimmed.substr (0 , 5 ) == " TOOL:" ) {
1489- std::string result = process_tool (trimmed, cfg. sandbox , cfg. run_allowed , tui);
1509+ std::string result = process_tool (trimmed, cfg, tui);
14901510 tui.append_line (" [tool] → " + result.substr (0 , 200 ));
14911511 tui.redraw_all ();
14921512 std::string tool_result_msg = " TOOL_RESULT: " + result;
@@ -1777,10 +1797,10 @@ static std::string tool_curl(const std::string &url) {
17771797// ═══════════════════════════════════════════════════════════════════════════
17781798// Tool dispatch
17791799// ═══════════════════════════════════════════════════════════════════════════
1780- static std::string process_tool (const std::string &cmd,
1781- const std::string &sandbox,
1782- const std::vector<std::string> &run_allowed,
1783- TuiState &tui) {
1800+ static std::string process_tool (const std::string &cmd, const NitroConfig &cfg, TuiState &tui) {
1801+ const std::string &sandbox = cfg. sandbox ;
1802+ const std::vector<std::string> &run_allowed = cfg. run_allowed ;
1803+
17841804 std::string op, arg1, arg2;
17851805 auto sp1 = cmd.find (' ' );
17861806 if (sp1 == std::string::npos) {
@@ -1848,6 +1868,9 @@ static std::string process_tool(const std::string &cmd,
18481868 if (op == " TOOL:CURL" ) {
18491869 return tool_curl (arg1);
18501870 }
1871+ if (op == " TOOL:INTROSPECT" ) {
1872+ return introspect (cfg);
1873+ }
18511874 if (op == " TOOL:RUN" ) {
18521875 std::string prog = resolve (arg1);
18531876 if (!path_in_sandbox (sandbox, prog)) return " ERROR: path outside sandbox" ;
@@ -1894,6 +1917,7 @@ static std::string build_system_prompt(const std::vector<std::string> &knowledge
18941917 " TOOL:TIME current time\n "
18951918 " TOOL:RND random float\n "
18961919 " TOOL:PERMISSION ask user for explicit permission\n "
1920+ " TOOL:INTROSPECT introspect your settings, top_k etc\n "
18971921 " TOOL:CURL <url> HTTP GET; returns response body (max 32 KB)\n\n "
18981922 " Rules:\n "
18991923 " - Never access files outside the sandbox.\n "
@@ -2084,8 +2108,9 @@ static void handle_slash(const std::string &input,
20842108 }
20852109
20862110 if (ok) {
2087- if (needs_reparam && agent.model_loaded )
2111+ if (needs_reparam && agent.model_loaded ) {
20882112 agent.apply_generation_params (cfg);
2113+ }
20892114 save_settings (cfg);
20902115 tui.append_line (" [sys] " + key + " = " + val);
20912116 }
@@ -2185,7 +2210,10 @@ int main(int argc, char **argv) {
21852210 std::error_code ec;
21862211 cfg.sandbox = fs::current_path (ec).string ();
21872212 }
2188- { std::error_code ec; fs::create_directories (cfg.sandbox , ec); }
2213+ {
2214+ std::error_code ec;
2215+ fs::create_directories (cfg.sandbox , ec);
2216+ }
21892217
21902218 // ── Auto-discover knowledge files ─────────────────────────────────
21912219 for (const char *kf : {" nitro.md" , " AGENTS.md" , " README.md" }) {
0 commit comments