fix(runtime): pass model through to the LLM API (+ UTF-8 JSON escaping) #53

Merged
will.anderson merged 3 commits from fix/llm-model-and-utf8 into stage 2026-06-10 22:01:52 +00:00
Showing only changes of commit 2b8062c55f - Show all commits
+36 -10
View File
@@ -3135,23 +3135,49 @@ static void jb_puts(JsonBuf* b, const char* s) {
static void jb_emit_escaped(JsonBuf* b, const char* s) {
jb_putc(b, '"');
for (; *s; s++) {
unsigned char c = (unsigned char)*s;
const unsigned char* p = (const unsigned char*)s;
while (*p) {
unsigned char c = *p;
switch (c) {
case '"': jb_puts(b, "\\\""); break;
case '\\': jb_puts(b, "\\\\"); break;
case '\b': jb_puts(b, "\\b"); break;
case '\f': jb_puts(b, "\\f"); break;
case '\n': jb_puts(b, "\\n"); break;
case '\r': jb_puts(b, "\\r"); break;
case '\t': jb_puts(b, "\\t"); break;
case '"': jb_puts(b, "\\\""); p++; break;
case '\\': jb_puts(b, "\\\\"); p++; break;
case '\b': jb_puts(b, "\\b"); p++; break;
case '\f': jb_puts(b, "\\f"); p++; break;
case '\n': jb_puts(b, "\\n"); p++; break;
case '\r': jb_puts(b, "\\r"); p++; break;
case '\t': jb_puts(b, "\\t"); p++; break;
default:
if (c < 0x20) {
char tmp[8];
snprintf(tmp, sizeof(tmp), "\\u%04x", c);
jb_puts(b, tmp);
} else {
p++;
} else if (c < 0x80) {
jb_putc(b, (char)c);
p++;
} else {
/* Multi-byte UTF-8: validate sequence, pass through if valid,
* escape as \u00xx if the start byte is invalid/orphaned. */
int seq_len = 0;
if ((c & 0xE0) == 0xC0) seq_len = 2;
else if ((c & 0xF0) == 0xE0) seq_len = 3;
else if ((c & 0xF8) == 0xF0) seq_len = 4;
if (seq_len >= 2) {
int valid = 1;
for (int i = 1; i < seq_len; i++) {
if ((p[i] & 0xC0) != 0x80) { valid = 0; break; }
}
if (valid) {
for (int i = 0; i < seq_len; i++) jb_putc(b, (char)p[i]);
p += seq_len;
break;
}
}
/* Invalid start byte or truncated sequence — escape it */
char tmp[8];
snprintf(tmp, sizeof(tmp), "\\u%04x", c);
jb_puts(b, tmp);
p++;
}
break;
}