Skip to content

Commit 6c212c0

Browse files
author
Chris Warren-Smith
committed
LLAMA: nitro - update thinking display
1 parent 966cda0 commit 6c212c0

1 file changed

Lines changed: 46 additions & 21 deletions

File tree

llama/nitro.cpp

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#include <algorithm>
4343
#include <chrono>
44+
#include <cmath>
4445
#include <ctime>
4546
#include <filesystem>
4647
#include <fstream>
@@ -469,7 +470,7 @@ static void load_settings(NitroConfig &cfg) {
469470
std::string json = oss.str();
470471

471472
cfg.thinking = true;
472-
473+
473474
// String fields
474475
settings_get_str(json, "model_path", cfg.model_path);
475476
settings_get_str(json, "embed_path", cfg.embed_path);
@@ -1170,23 +1171,30 @@ void TuiState::redraw_input() const {
11701171
ncplane_erase(inputpl);
11711172

11721173
if (thinking) {
1173-
static constexpr const char *ROBOT_RIGHT = "🤖➡";
1174-
static constexpr const char *ROBOT_LEFT = "⬅🤖";
1175-
// 15 steps each way = 20 frame cycle
1176-
static constexpr int STEPS = 15;
1177-
int cycle = spinner_frame % (STEPS * 2);
1178-
bool going_right = (cycle < STEPS);
1179-
int pos = going_right ? cycle : (STEPS * 2 - 1 - cycle);
1180-
1181-
std::string sep(term_cols, '-');
1182-
// blank 4 cols to fit robot + arrow (each emoji is 2 cols wide)
1183-
for (int i = pos; i < std::min(pos + 4, term_cols); ++i) sep[i] = ' ';
1184-
ncplane_set_channels(inputpl, inp_ch(80, 120, 160));
1185-
ncplane_putstr_yx(inputpl, 0, 0, sep.c_str());
1186-
1187-
ncplane_set_channels(inputpl, NCCHANNELS_INITIALIZER(255, 220, 80, BG_INP_R, BG_INP_G, BG_INP_B));
1188-
ncplane_putstr_yx(inputpl, 0, pos, going_right ? ROBOT_RIGHT : ROBOT_LEFT);
1189-
1174+
static constexpr const char *BLOCKS[] = { "-", "~", "", "~", "-" };
1175+
static constexpr int N_BLOCKS = 5;
1176+
static constexpr double FREQ = 0.25; // gentler wave
1177+
static constexpr double SPEED = 0.15; // slower scroll
1178+
static constexpr int DELAY = 12; // frames before animation starts
1179+
1180+
if (spinner_frame < DELAY) {
1181+
// still just a plain separator during the pause
1182+
ncplane_set_channels(inputpl, inp_ch(80, 120, 160));
1183+
std::string sep(term_cols, '-');
1184+
ncplane_putstr_yx(inputpl, 0, 0, sep.c_str());
1185+
} else {
1186+
int frame = spinner_frame - DELAY; // animation frame relative to start
1187+
for (int col = 0; col < term_cols; ++col) {
1188+
double phase = (col * FREQ) - (frame * SPEED);
1189+
int idx = (int)((std::sin(phase) + 1.0) * 0.5 * (N_BLOCKS - 1));
1190+
idx = std::max(0, std::min(idx, N_BLOCKS - 1));
1191+
// subtle brightness shift — blue-grey, not full glow
1192+
int brightness = 80 + idx * 20;
1193+
ncplane_set_channels(inputpl, NCCHANNELS_INITIALIZER(brightness, brightness + 20, brightness + 40,
1194+
BG_INP_R, BG_INP_G, BG_INP_B));
1195+
ncplane_putstr_yx(inputpl, 0, col, BLOCKS[idx]);
1196+
}
1197+
}
11901198
ncplane_set_channels(inputpl, inp_ch(140, 140, 180));
11911199
ncplane_putstr_yx(inputpl, 1, 2, "thinking…");
11921200
} else {
@@ -1787,7 +1795,7 @@ bool AgentState::setup_model(const NitroConfig &cfg, TuiState &tui) {
17871795
tui.vram_total = mem.vram_total;
17881796

17891797
tui.append_line(std::string("[sys] Thinking mode: ") + (cfg.thinking ? "enabled" : "disabled"));
1790-
tui.redraw_all();
1798+
tui.redraw_all();
17911799
return true;
17921800
}
17931801

@@ -2070,6 +2078,7 @@ bool AgentState::run_turn(const std::string &user_message, const NitroConfig &cf
20702078
// in_think starts false — models that don't use <think> blocks emit
20712079
// visible text immediately. The spinner activates only while thinking.
20722080
enum {t_init, t_think, t_thunk} think_mode = (cfg.thinking ? t_init : t_thunk);
2081+
20732082
tui.set_thinking(false);
20742083
std::string buffer;
20752084

@@ -2089,7 +2098,7 @@ bool AgentState::run_turn(const std::string &user_message, const NitroConfig &cf
20892098
tool = buffer;
20902099
}
20912100

2092-
log_write("tool request: [%s]", tool.c_str());
2101+
log_write("tool request: mode:[%d] [%s]", think_mode, tool.c_str());
20932102
std::string result = process_tool(tool, cfg, tui);
20942103
std::string content = TOOL_RESULT + std::vformat(template_str, std::make_format_args(result));
20952104
log_write("tool: [%s] result: [%s]", tool.c_str(), result.c_str());
@@ -2137,7 +2146,23 @@ bool AgentState::run_turn(const std::string &user_message, const NitroConfig &cf
21372146
return false;
21382147
}
21392148
std::string tok = llama->next(*iter);
2140-
buffer += tok;
2149+
if (tok == "<") {
2150+
// fetch the complete tag
2151+
std::string tag = tok;
2152+
while (iter->_has_next && tag.find(">") == std::string::npos) {
2153+
tag += llama->next(*iter);
2154+
}
2155+
if (tag == "<|think|>") {
2156+
think_mode = t_think;
2157+
tui.set_thinking(true);
2158+
continue;
2159+
} else {
2160+
buffer += tag;
2161+
}
2162+
} else {
2163+
buffer += tok;
2164+
}
2165+
21412166
if (think_mode == t_init) {
21422167
start_think("<think>");
21432168
start_think("<|think|>");

0 commit comments

Comments
 (0)