Route ordinary assistant bytes either to normal markdown rendering or into * the DSML detector. The detector must hold short prefixes because the model * can split "<|DSML|tool_calls>" across arbitrary tokens. */
| 3336 | r->md_code_line_prefix_color = color; |
| 3337 | } |
| 3338 | |
| 3339 | static void renderer_code_stream_set_upto_marker(agent_token_renderer *r, |
| 3340 | bool enabled) { |
| 3341 | r->md_code_highlight_upto = enabled; |
| 3342 | } |
| 3343 | |
| 3344 | static void renderer_code_end(agent_token_renderer *r) { |
| 3345 | bool only_space = true; |
| 3346 | for (size_t i = 0; i < r->md_code_line_len; i++) { |
| 3347 | if (r->md_code_line[i] != ' ' && r->md_code_line[i] != '\t' && |
| 3348 | r->md_code_line[i] != '\r') { |
| 3349 | only_space = false; |
| 3350 | break; |
| 3351 | } |
| 3352 | } |
| 3353 | if (r->md_code_line_len && !only_space) |
| 3354 | renderer_code_emit_buffered_line(r, false); |
| 3355 | else |
| 3356 | r->md_code_line_len = 0; |
| 3357 | r->md_code_block = false; |
| 3358 | r->md_inline_code = false; |
| 3359 | r->md_fence_info = false; |
| 3360 | r->md_code_line_start = true; |
| 3361 | r->md_code_in_ml_comment = false; |
| 3362 | r->md_syntax = NULL; |
| 3363 | r->md_fence_lang_len = 0; |
| 3364 | r->md_fence_lang[0] = '\0'; |
| 3365 | r->md_code_line_prefix = NULL; |
| 3366 | r->md_code_line_prefix_color = NULL; |
| 3367 | } |
| 3368 | |
| 3369 | /* Tool visualization and redirected output bypass Markdown formatting. */ |
| 3370 | static void renderer_markdown_clear_pending(agent_token_renderer *r) { |
| 3371 | r->md_pending = AGENT_MD_PENDING_NONE; |
| 3372 | r->md_pending_len = 0; |
| 3373 | } |
| 3374 | |
| 3375 | static bool renderer_markdown_inline_pair(agent_token_renderer *r, size_t *delimiter) { |
| 3376 | size_t n = r->md_inline_len, open = 1, close = 0; |
| 3377 | char ch = r->md_inline[0]; |
| 3378 | while (open < n && r->md_inline[open] == ch) open++; |
| 3379 | while (close < n && r->md_inline[n - close - 1] == ch) close++; |
| 3380 | *delimiter = open; |
| 3381 | if (open > 2 || close != open || n <= open + close) return false; |
| 3382 | if (ch == '*') { |
| 3383 | if (isspace((unsigned char)r->md_inline[open]) || |
| 3384 | isspace((unsigned char)r->md_inline[n - close - 1])) return false; |
| 3385 | size_t escapes = 0, pos = n - close; |
| 3386 | while (pos && r->md_inline[--pos] == '\\') escapes++; |
| 3387 | if (escapes & 1) return false; |
| 3388 | } |
| 3389 | return true; |
| 3390 | } |
| 3391 | |
| 3392 | static void renderer_markdown_inline_flush(agent_token_renderer *r, bool format) { |
| 3393 | size_t n = r->md_inline_len, delimiter = 0; |
| 3394 | if (!n) return; |
| 3395 | bool paired = format && renderer_markdown_inline_pair(r, &delimiter); |
no test coverage detected