code wiki / _hdl_build / nx_write.nx

nx_write.nx source

↩ module page · 488 lines · 22055 B

1// nx_write.nx -- W-BB-1: THE WRITE LANE'S BACKBONE. The organ that actually WRITES. 2// 3// u2605u2605u2605u2605u2605u2605THE GAP THIS CLOSES, AND IT IS EMBARRASSING IN THE RIGHT WAY. The write lane had a ruler 4// (nx_writebench, 625 permil), a panel-reliability bound, a real-person gate, a greeting-structure 5// grader, a campaign continuity checker and a per-turn dialogue meter -- and NO GENERATOR. 6// `nx_writer_run` is 9 functions that emit scaffolding and contain no inference call whatsoever: no 7// engine, no model, no HTTP. Meanwhile the local engine answers /v1/chat/completions in ~1.4s and 8// has all along; the gen lane has been using it for images and chat for weeks. 9// u21d2 WE HAD BUILT GRADERS FOR A THING THAT COULD NOT PRODUCE. 10// u2605u2605u2605u2605u2605u2605A LANE WITH RULERS AND NO PRODUCER MEASURES NOTHING -- COVERAGE ON AN EMPTY LANE IS A 11// NUMBER ABOUT THE RULER, NOT ABOUT A CAPABILITY. 12// 13// WHAT THIS IS: prompt -> real prose, on the local engine, for every mode in the registry -- 14// the writing equivalent of what nx_gen is for images. 15// 16// u2605THE SEAM IS ENFORCED BY CONSTRUCTION, NOT BY POLICY TEXT. write_modes.tsv declares per mode a 17// REGISTER (sfw|mixed|explicit) and a LANE (tutor|local). An `explicit` mode may only run on the 18// `local` lane -- it never leaves this machine. That is a routing fact checked here before a single 19// byte is sent, so it cannot be forgotten by a caller or argued away by a prompt. 20// 21// u2605ENDPOINT FROM THE SWARM SSOT, never a literal: se_addr("gpu-image") -- the same single source the 22// gen daemon resolves per request, so a DHCP move heals both lanes at once (the 6-hardcoded-sites 23// outage is not repeated here). 24// 25// nx_write <mode> <prompt...> -- generate; prose to stdout 26// nx_write modes -- list the registry 27// license_tier: ORIGINAL expect_exit: 0 28// module: nishi-core.write.backbone 29import "nx_syscalls.nx" 30import "nx_estate_path.nx" 31import "nx_connect.nx" 32import "nx_swarm_endpoint_lib.nx" 33import "nx_store_seed_lib.nx" 34import "nx_lane_conf.nx" 35const W_MAGIC_4096: i64 = 4096 36// THE MODE REGISTRY IS A SEG-STORE PLANE (info-plane doctrine 2026-08-01: registries are planes, 37// never TSVs). Seed/refresh via `nx_write migrate` (reads the tombstoned tsv one more time and 38// re-seeds); every lookup reads the plane and FAILS CLOSED if it is unseeded -- a silent tsv 39// fallback here would be a forked SSOT wearing a convenience. 40const W_PLANE: *u8 = "knowledge/store/writemode-" 41 42const W_BUF: i64 = 1048576 43const W_REQ: i64 = 262144 44// u26a0the three below are ABSENT-CONF FALLBACKS ONLY (rule 11): the live values are rows in 45// knowledge/write_lane.conf, hot-read via nx_lane_conf -- edit the conf, never these. 46const W_TMO_SEC: i64 = 300 47const W_MAXTOK: i64 = 1200 48const W_LEN_MIN: i64 = 200 49const W_LEN_MAX: i64 = 8000 50 51func ww(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 52func we(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(2, s, n); return 0 } 53func w_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 54func w_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; var a: i64 = o; while s[i] != (0 as u8) { d[a] = s[i]; a = a + 1; i = i + 1 } return a } 55func w_catn(d: *u8, o: i64, v: i64) -> i64 { 56 let t: *u8 = sys_mmap(32) 57 var m: i64 = v; var k: i64 = 0 58 if m == 0 { t[0] = 48 as u8; k = 1 } 59 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 60 var a: i64 = o; var j: i64 = k - 1 61 while j >= 0 { d[a] = t[j]; a = a + 1; j = j - 1 } 62 return a 63} 64// JSON-escape into dst 65func w_jesc(d: *u8, o: i64, s: *u8) -> i64 { 66 var a: i64 = o; var i: i64 = 0 67 while s[i] != (0 as u8) { 68 let c: i64 = s[i] & 0xff 69 if c == 34 { d[a] = 92 as u8; a = a + 1; d[a] = 34 as u8; a = a + 1 } 70 else { if c == 92 { d[a] = 92 as u8; a = a + 1; d[a] = 92 as u8; a = a + 1 } 71 else { if c == 10 { d[a] = 92 as u8; a = a + 1; d[a] = 110 as u8; a = a + 1 } 72 else { if c < 32 { d[a] = 32 as u8; a = a + 1 } else { d[a] = s[i]; a = a + 1 } } } } 73 i = i + 1 74 } 75 return a 76} 77func w_slurp(path: *u8, buf: *u8, cap: i64) -> i64 { 78 let fd: i64 = ep_open_rd(path) 79 if fd < 0 { return 0 - 1 } 80 var t: i64 = 0 81 var r: i64 = 1 82 while r > 0 { 83 if t >= cap { r = 0 } else { r = sys_read(fd, ((buf as i64) + t) as *u8, cap - t); if r > 0 { t = t + r } } 84 } 85 sys_close(fd) 86 return t 87} 88func w_streq(a: *u8, b: *u8) -> i64 { 89 var i: i64 = 0 90 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } 91 if b[i] != (0 as u8) { return 0 } 92 return 1 93} 94// copy field <idx> (tab-separated) of row [s,e) into out; returns length 95func w_field(buf: *u8, s: i64, e: i64, idx: i64, out: *u8, cap: i64) -> i64 { 96 var p: i64 = s 97 var f: i64 = 0 98 while f < idx { 99 var go: i64 = 1 100 while go == 1 { 101 if p >= e { go = 0 } else { if buf[p] == (9 as u8) { p = p + 1; go = 0 } else { p = p + 1 } } 102 } 103 f = f + 1 104 } 105 if p >= e { out[0] = 0 as u8; return 0 } 106 var k: i64 = 0 107 while p < e { 108 if buf[p] == (9 as u8) { p = e } else { 109 if k < cap - 1 { out[k] = buf[p]; k = k + 1 } 110 p = p + 1 111 } 112 } 113 out[k] = 0 as u8 114 return k 115} 116 117// parse unsigned digits from s starting at pi[0]; advances pi past them. 0 if none. 118func w_atoi(s: *u8, pi: *i64) -> i64 { 119 var i: i64 = pi[0] 120 var v: i64 = 0 121 var run: i64 = 1 122 while run == 1 { 123 if s[i] < (48 as u8) { run = 0 } else { 124 if s[i] > (57 as u8) { run = 0 } else { v = v*10 + ((s[i] as i64) - 48); i = i + 1 } 125 } 126 } 127 pi[0] = i 128 return v 129} 130 131// look up a mode row -> register/lane/structure (+ optional col5 max_tokens, col6 arc). 132// Old 5-column rows stay valid: missing fields come back empty -> caller defaults. 1 = found. 133func w_mode_lookup(mode: *u8, reg: *u8, lane: *u8, structure: *u8, mtok: *u8, arc: *u8) -> i64 { 134 let buf: *u8 = sys_mmap(W_BUF) 135 let n: i64 = sts_load(W_PLANE, buf, W_BUF) 136 if n <= 0 { return 0 - 1 } 137 let nm: *u8 = sys_mmap(128) 138 var p: i64 = 0 139 while p < n { 140 var e: i64 = n 141 var q: i64 = p 142 var go: i64 = 1 143 while go == 1 { 144 if q >= n { e = n; go = 0 } else { if buf[q] == (10 as u8) { e = q; go = 0 } else { q = q + 1 } } 145 } 146 if e > p { 147 if buf[p] != (35 as u8) { // skip comments 148 w_field(buf, p, e, 0, nm, 128) 149 if w_streq(nm, mode) == 1 { 150 w_field(buf, p, e, 1, reg, 64) 151 w_field(buf, p, e, 2, lane, 64) 152 w_field(buf, p, e, 3, structure, 64) 153 w_field(buf, p, e, 5, mtok, 16) 154 w_field(buf, p, e, 6, arc, 16) 155 return 1 156 } 157 } 158 } 159 p = e + 1 160 } 161 return 0 162} 163 164func w_list_modes() -> i64 { 165 let buf: *u8 = sys_mmap(W_BUF) 166 let n: i64 = sts_load(W_PLANE, buf, W_BUF) 167 if n <= 0 { we("nx_write: writemode- plane unseeded -- run `nx_write migrate` once\n\x00" as *u8); return 1 } 168 ww("# writemode- plane (SSOT; columns: mode register lane structure description [max_tokens] [arc])\n" as *u8) 169 sys_write(1, buf, n) 170 return 0 171} 172 173// one-time (re)seed: read the tombstoned tsv, keep DATA rows only, sts_seed the plane, report parity. 174func w_migrate() -> i64 { 175 let raw: *u8 = sys_mmap(W_BUF) 176 let n: i64 = w_slurp("knowledge/registry/write_modes.tsv" as *u8, raw, W_BUF) 177 if n <= 0 { we("nx_write migrate: write_modes.tsv unreadable\n\x00" as *u8); return 1 } 178 let clean: *u8 = sys_mmap(W_BUF) 179 var co: i64 = 0 180 var tsvrows: i64 = 0 181 var p: i64 = 0 182 while p < n { 183 var e: i64 = p 184 var go: i64 = 1 185 while go == 1 { 186 if e >= n { go = 0 } else { if raw[e] == (10 as u8) { go = 0 } else { e = e + 1 } } 187 } 188 if e > p { if raw[p] != (35 as u8) { 189 var q: i64 = p 190 while q < e { clean[co] = raw[q]; co = co + 1; q = q + 1 } 191 clean[co] = 10 as u8; co = co + 1 192 tsvrows = tsvrows + 1 193 } } 194 p = e + 1 195 } 196 let seeded: i64 = sts_seed(W_PLANE, clean, co) 197 ww("WRITEMODE-MIGRATE tsv_rows=" as *u8) 198 let nb: *u8 = sys_mmap(32) 199 var nn: i64 = w_catn(nb, 0, tsvrows) 200 sys_write(1, nb, nn) 201 ww(" plane_rows=" as *u8) 202 nn = w_catn(nb, 0, seeded) 203 sys_write(1, nb, nn) 204 if seeded == tsvrows { ww(" PARITY-OK (plane is now the SSOT; tsv is a tombstone)\n" as *u8); return 0 } 205 ww(" PARITY-FAIL -- do not tombstone, investigate\n" as *u8) 206 return 1 207} 208 209// system prompt per STRUCTURE -- the registry's own column drives it, so adding a mode is a row edit. 210// arc column: "complete" = carry the piece through its FULL arc (the fade-out class: a scene prompt 211// that says "end on a beat that invites what comes next" plus a token ceiling reads as coy 212// truncation -- for modes that declare complete, the ending is part of the deliverable). 213func w_system_for(structure: *u8, arc: *u8, out: *u8) -> i64 { 214 var o: i64 = w_cat(out, 0, "You are a skilled prose writer. Write the piece itself with no preamble, no meta-commentary, and no headings unless the form requires them. " as *u8) 215 if w_streq(structure, "scene" as *u8) == 1 { 216 o = w_cat(out, o, "Write a scene: establish who is present and where, let something happen, and end on a beat that invites what comes next. Concrete sensory detail over summary." as *u8) 217 } else { if w_streq(structure, "scenario" as *u8) == 1 { 218 o = w_cat(out, o, "Open a scenario the reader can step into. Three beats: introduce the speaker, establish the situation already in motion, then address the reader directly and hand them the move." as *u8) 219 } else { if w_streq(structure, "panel" as *u8) == 1 { 220 o = w_cat(out, o, "Write a page script as numbered PANEL blocks. Each panel: one line of visual description, then any dialogue." as *u8) 221 } else { if w_streq(structure, "tone" as *u8) == 1 { 222 o = w_cat(out, o, "Match the requested voice closely. Keep sentence rhythm and diction consistent throughout." as *u8) 223 } else { if w_streq(structure, "imrad" as *u8) == 1 { 224 o = w_cat(out, o, "Use IMRaD structure: Introduction, Methods, Results, Discussion. Be precise and cite nothing you cannot support." as *u8) 225 } else { if w_streq(structure, "convo" as *u8) == 1 { 226 o = w_cat(out, o, "Write a natural back-and-forth conversation that keeps the topic moving." as *u8) 227 } else { 228 o = w_cat(out, o, "Write clearly and vividly in the form the request implies." as *u8) 229 } } } } } } 230 if w_streq(arc, "complete" as *u8) == 1 { 231 o = w_cat(out, o, " Carry the piece through its FULL arc to an actual conclusion: the events themselves happen on the page, rendered at the same sensory depth as the rest -- never summarize past them, never fade out, never stop short. The piece ends only after its climax and a brief settling beat." as *u8) 232 } 233 out[o] = 0 as u8 234 return o 235} 236 237// POST /v1/chat/completions to a.b.c.d:port; response into resp. returns length, -1 on failure. 238func w_engine_call(a: i64, b: i64, c: i64, d: i64, port: i64, req: *u8, reqlen: i64, resp: *u8, cap: i64) -> i64 { 239 let fd: i64 = sys_socket(2, 1, 0) 240 if fd < 0 { return 0 - 1 } 241 sys_set_socket_timeout(fd, W_TMO_SEC) 242 let sa: *u8 = sys_mmap(16) 243 sa[0] = 2 as u8; sa[1] = 0 as u8 244 sa[2] = ((port >> 8) & 0xff) as u8; sa[3] = (port & 0xff) as u8 245 sa[4] = a as u8; sa[5] = b as u8; sa[6] = c as u8; sa[7] = d as u8 246 var z: i64 = 8 247 while z < 16 { sa[z] = 0 as u8; z = z + 1 } 248 if nx_connect_bounded(fd, sa, 16, NX_CONN_DEFAULT_MS) != 0 { sys_close(fd); return 0 - 1 } 249 sys_write(fd, req, reqlen) 250 var t: i64 = 0 251 var r: i64 = 1 252 while r > 0 { 253 if t >= cap { r = 0 } else { r = sys_read(fd, ((resp as i64) + t) as *u8, cap - t); if r > 0 { t = t + r } } 254 } 255 sys_close(fd) 256 return t 257} 258 259// try-connect only: 0 = reachable, nonzero = not. Bounded like every other connect here, so an 260// absent/firewalled brain costs one connect window, never a read timeout. 261func w_probe(a: i64, b: i64, c: i64, d: i64, port: i64) -> i64 { 262 let fd: i64 = sys_socket(2, 1, 0) 263 if fd < 0 { return 0 - 1 } 264 let sa: *u8 = sys_mmap(16) 265 sa[0] = 2 as u8; sa[1] = 0 as u8 266 sa[2] = ((port >> 8) & 0xff) as u8; sa[3] = (port & 0xff) as u8 267 sa[4] = a as u8; sa[5] = b as u8; sa[6] = c as u8; sa[7] = d as u8 268 var z: i64 = 8 269 while z < 16 { sa[z] = 0 as u8; z = z + 1 } 270 let rc: i64 = nx_connect_bounded(fd, sa, 16, NX_CONN_DEFAULT_MS) 271 sys_close(fd) 272 if rc != 0 { return 0 - 1 } 273 return 0 274} 275 276// pull the assistant text out of {"choices":[{"message":{"content":"..."}}]} and unescape it. 277func w_extract(resp: *u8, n: i64) -> i64 { 278 let key: *u8 = "\"content\":\"" as *u8 279 let kl: i64 = w_len(key) 280 var i: i64 = 0 281 var s: i64 = 0 - 1 282 while i + kl <= n { 283 var j: i64 = 0 284 var same: i64 = 1 285 while j < kl { if resp[i + j] != key[j] { same = 0; j = kl } else { j = j + 1 } } 286 if same == 1 { s = i + kl; i = n } else { i = i + 1 } 287 } 288 if s < 0 { return 0 - 1 } 289 let out: *u8 = sys_mmap(W_BUF) 290 var o: i64 = 0 291 var p: i64 = s 292 var go: i64 = 1 293 while go == 1 { 294 if p >= n { go = 0 } else { 295 let ch: i64 = resp[p] & 0xff 296 if ch == 34 { go = 0 } 297 else { 298 if ch == 92 { 299 let nx: i64 = resp[p + 1] & 0xff 300 if nx == 110 { out[o] = 10 as u8; o = o + 1; p = p + 2 } 301 else { if nx == 116 { out[o] = 9 as u8; o = o + 1; p = p + 2 } 302 else { out[o] = resp[p + 1]; o = o + 1; p = p + 2 } } 303 } else { out[o] = resp[p]; o = o + 1; p = p + 1 } 304 } 305 } 306 } 307 sys_write(1, out, o) 308 ww("\n\x00" as *u8) 309 return o 310} 311 312// parse "a.b.c.d:port" into w[0..4]; 1 = ok 313func w_parse_addr(s: *u8, w: *i64) -> i64 { 314 var i: i64 = 0 315 var f: i64 = 0 316 while f < 5 { 317 var v: i64 = 0 318 var dig: i64 = 0 319 var scan: i64 = 1 320 while scan == 1 { 321 let c: i64 = s[i] as i64 322 if c < 48 { scan = 0 } else { if c > 57 { scan = 0 } else { v = v * 10 + (c - 48); dig = dig + 1; i = i + 1 } } 323 } 324 if dig == 0 { return 0 } 325 w[f] = v 326 f = f + 1 327 if f < 5 { i = i + 1 } // skip the '.' or ':' 328 } 329 return 1 330} 331 332func main(argc: i64, argv: *i64) -> i64 { 333 ep_anchor() 334 if argc < 2 { 335 ww("usage: nx_write <mode> <prompt...> | nx_write modes\n\x00" as *u8) 336 return 1 337 } 338 let mode: *u8 = argv[1] as *u8 339 if w_streq(mode, "modes" as *u8) == 1 { return w_list_modes() } 340 if w_streq(mode, "migrate" as *u8) == 1 { return w_migrate() } 341 if argc < 3 { we("nx_write: needs a prompt\n\x00" as *u8); return 2 } 342 343 let reg: *u8 = sys_mmap(64) 344 let lane: *u8 = sys_mmap(64) 345 let structure: *u8 = sys_mmap(64) 346 let mtok: *u8 = sys_mmap(16) 347 let arc: *u8 = sys_mmap(16) 348 let found: i64 = w_mode_lookup(mode, reg, lane, structure, mtok, arc) 349 if found < 0 { we("nx_write: writemode- plane unseeded/unreadable (the plane is the SSOT; nothing is guessed) -- run `nx_write migrate`\n\x00" as *u8); return 3 } 350 if found == 0 { 351 we("nx_write: unknown mode -- run `nx_write modes` for the registry\n\x00" as *u8) 352 return 4 353 } 354 355 // u2605THE SEAM, CHECKED BEFORE A BYTE IS SENT: an explicit register may only run on the local lane. 356 if w_streq(reg, "explicit" as *u8) == 1 { 357 if w_streq(lane, "local" as *u8) == 0 { 358 we("nx_write REFUSED: mode is register=explicit but lane=\x00" as *u8); we(lane) 359 we(" -- an explicit register may only run on the local lane. Fix the registry row, not this call.\n\x00" as *u8) 360 return 5 361 } 362 } 363 364 // SPOKE-YIELD ADMISSION (operator 2026-08-05): if the spoke's sentinel reports an interactive 365 // GPU tenant (a game), the swarm YIELDS -- interactive sessions outrank batch generation. The 366 // hub is not brought down and nothing is lost: the writer's async lane keeps the request as a 367 // durable .req and the sweeper runs it when the GPU frees. Conf-driven (gpu_yield_to_games). 368 if lc_write_lane("gpu_yield_to_games" as *u8, 1) == 1 { 369 let gb: *u8 = sys_mmap(256) 370 let gn: i64 = w_slurp("knowledge/status/gpu_avail.conf" as *u8, gb, 250) 371 if gn > 0 { 372 let gp: *i64 = sys_mmap(16) as *i64 373 gp[0] = 0 374 let gep: i64 = w_atoi(gb, gp) 375 let nowt: *i64 = sys_mmap(16) as *i64 376 nowt[0] = 0 377 sys_clock_gettime_real(nowt) 378 if nowt[0] - gep < lc_write_lane("gpu_avail_max_age_sec" as *u8, 180) { 379 var gi: i64 = 0 380 var isgame: i64 = 0 381 while gi + 5 < gn { 382 if gb[gi]==(103 as u8) { if gb[gi+1]==(97 as u8) { if gb[gi+2]==(109 as u8) { if gb[gi+3]==(101 as u8) { if gb[gi+4]==(61 as u8) { 383 if gb[gi+5]==(110 as u8) { if gb[gi+6]==(111 as u8) { if gb[gi+7]==(110 as u8) { if gb[gi+8]==(101 as u8) { isgame = 0-1 } } } } 384 if isgame == 0 { isgame = 1 } 385 gi = gn 386 } } } } } 387 gi = gi + 1 388 } 389 if isgame == 1 { 390 ww("NX-WRITE-DEFERRED gpu yielded to interactive session (sentinel: game present); queued jobs run when the gpu frees\n" as *u8) 391 return 0 392 } 393 } 394 } 395 } 396 397 // endpoint from the swarm SSOT -- prefer the dedicated write brain (gpu-write, llama-server), 398 // fall back to the image engine's chat lane (gpu-image). Both rows live in knowledge/swarm_nodes.conf; 399 // adding/moving a brain is a ROW EDIT, never a code edit. u2605RESOLVE IS NOT REACHABLE (the swarm 400 // co_usable lesson): the preferred role must also PROBE-CONNECT, else a firewalled brain wedges 401 // the lane that a healthy fallback could serve. 402 var addr: *u8 = se_addr("gpu-write" as *u8) 403 if (addr as i64) != 0 { 404 let wp: *i64 = sys_mmap(64) as *i64 405 if w_parse_addr(addr, wp) == 1 { 406 if w_probe(wp[0], wp[1], wp[2], wp[3], wp[4]) != 0 { addr = 0 as *u8 } 407 } else { addr = 0 as *u8 } 408 } 409 if (addr as i64) == 0 { addr = se_addr("gpu-image" as *u8) } 410 if (addr as i64) == 0 { 411 we("nx_write: neither gpu-write nor gpu-image resolvable in knowledge/swarm_nodes.conf (fail-closed; no fabricated endpoint)\n\x00" as *u8) 412 return 6 413 } 414 let w4: *i64 = sys_mmap(64) as *i64 415 if w_parse_addr(addr, w4) == 0 { we("nx_write: malformed endpoint row\n\x00" as *u8); return 6 } 416 417 // length: registry col5 (per mode) -> conf default; a leading len=<N> prompt token 418 // overrides per call, clamped to the conf min/max. 419 var toks: i64 = lc_write_lane("write_default_max_tokens" as *u8, W_MAXTOK) 420 let lmin: i64 = lc_write_lane("write_len_min" as *u8, W_LEN_MIN) 421 let lmax: i64 = lc_write_lane("write_len_max" as *u8, W_LEN_MAX) 422 if mtok[0] != (0 as u8) { 423 let mp: *i64 = sys_mmap(16) as *i64 424 mp[0] = 0 425 let mv: i64 = w_atoi(mtok, mp) 426 if mv > 0 { toks = mv } 427 } 428 // len=<N> may arrive as its OWN argv token (CLI) or as the PREFIX of a single prompt string 429 // (the /write daemon passes the whole body as one arg) -- handle both. 430 var ai: i64 = 2 431 var a2off: i64 = 0 432 let a2: *u8 = argv[2] as *u8 433 if a2[0] == (108 as u8) { if a2[1] == (101 as u8) { if a2[2] == (110 as u8) { if a2[3] == (61 as u8) { 434 let lp: *i64 = sys_mmap(16) as *i64 435 lp[0] = 4 436 let lv: i64 = w_atoi(a2, lp) 437 if lv >= lmin { if lv <= lmax { 438 toks = lv 439 if a2[lp[0]] == (0 as u8) { ai = 3 } else { 440 if a2[lp[0]] == (32 as u8) { a2off = lp[0] + 1 } 441 } 442 } } 443 } } } } 444 if ai >= argc { if a2off == 0 { we("nx_write: needs a prompt after len=\n\x00" as *u8); return 2 } } 445 446 // assemble the prompt from argv[ai..] (a2off skips a consumed len= prefix inside argv[2]) 447 let user: *u8 = sys_mmap(W_REQ) 448 var uo: i64 = 0 449 while ai < argc { 450 if uo > 0 { user[uo] = 32 as u8; uo = uo + 1 } 451 if ai == 2 { uo = w_cat(user, uo, ((a2 as i64) + a2off) as *u8) } else { uo = w_cat(user, uo, argv[ai] as *u8) } 452 ai = ai + 1 453 } 454 user[uo] = 0 as u8 455 456 let sysp: *u8 = sys_mmap(W_MAGIC_4096) 457 w_system_for(structure, arc, sysp) 458 459 let body: *u8 = sys_mmap(W_REQ) 460 var bo: i64 = w_cat(body, 0, "{\"model\":\"local\",\"max_tokens\":" as *u8) 461 bo = w_catn(body, bo, toks) 462 bo = w_cat(body, bo, ",\"messages\":[{\"role\":\"system\",\"content\":\"" as *u8) 463 bo = w_jesc(body, bo, sysp) 464 bo = w_cat(body, bo, "\"},{\"role\":\"user\",\"content\":\"" as *u8) 465 bo = w_jesc(body, bo, user) 466 bo = w_cat(body, bo, "\"}]}" as *u8) 467 468 let req: *u8 = sys_mmap(W_REQ) 469 var ro: i64 = w_cat(req, 0, "POST /v1/chat/completions HTTP/1.1\r\nHost: engine\r\nConnection: close\r\nContent-Type: application/json\r\nContent-Length: " as *u8) 470 ro = w_catn(req, ro, bo) 471 ro = w_cat(req, ro, "\r\n\r\n" as *u8) 472 var bi: i64 = 0 473 while bi < bo { req[ro] = body[bi]; ro = ro + 1; bi = bi + 1 } 474 475 let resp: *u8 = sys_mmap(W_BUF) 476 let rn: i64 = w_engine_call(w4[0], w4[1], w4[2], w4[3], w4[4], req, ro, resp, W_BUF) 477 if rn <= 0 { 478 we("nx_write: engine unreachable at \x00" as *u8); we(addr) 479 we(" -- is the local engine up? (nishi_elara_engine_keeper.ps1)\n\x00" as *u8) 480 return 7 481 } 482 if w_extract(resp, rn) < 0 { 483 we("nx_write: engine replied but no content field -- raw response follows on stderr\n\x00" as *u8) 484 sys_write(2, resp, rn) 485 return 8 486 } 487 return 0 488}