code wiki / _hdl_build / nx_write.nx
nx_write.nx source
↩ module page · 489 lines · 22110 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 { d[o] = 45 as u8; o = o + 1; m = 0 - m }
59 if m == 0 { t[0] = 48 as u8; k = 1 }
60 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
61 var a: i64 = o; var j: i64 = k - 1
62 while j >= 0 { d[a] = t[j]; a = a + 1; j = j - 1 }
63 return a
64}
65// JSON-escape into dst
66func w_jesc(d: *u8, o: i64, s: *u8) -> i64 {
67 var a: i64 = o; var i: i64 = 0
68 while s[i] != (0 as u8) {
69 let c: i64 = s[i] & 0xff
70 if c == 34 { d[a] = 92 as u8; a = a + 1; d[a] = 34 as u8; a = a + 1 }
71 else { if c == 92 { d[a] = 92 as u8; a = a + 1; d[a] = 92 as u8; a = a + 1 }
72 else { if c == 10 { d[a] = 92 as u8; a = a + 1; d[a] = 110 as u8; a = a + 1 }
73 else { if c < 32 { d[a] = 32 as u8; a = a + 1 } else { d[a] = s[i]; a = a + 1 } } } }
74 i = i + 1
75 }
76 return a
77}
78func w_slurp(path: *u8, buf: *u8, cap: i64) -> i64 {
79 let fd: i64 = ep_open_rd(path)
80 if fd < 0 { return 0 - 1 }
81 var t: i64 = 0
82 var r: i64 = 1
83 while r > 0 {
84 if t >= cap { r = 0 } else { r = sys_read(fd, ((buf as i64) + t) as *u8, cap - t); if r > 0 { t = t + r } }
85 }
86 sys_close(fd)
87 return t
88}
89func w_streq(a: *u8, b: *u8) -> i64 {
90 var i: i64 = 0
91 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 }
92 if b[i] != (0 as u8) { return 0 }
93 return 1
94}
95// copy field <idx> (tab-separated) of row [s,e) into out; returns length
96func w_field(buf: *u8, s: i64, e: i64, idx: i64, out: *u8, cap: i64) -> i64 {
97 var p: i64 = s
98 var f: i64 = 0
99 while f < idx {
100 var go: i64 = 1
101 while go == 1 {
102 if p >= e { go = 0 } else { if buf[p] == (9 as u8) { p = p + 1; go = 0 } else { p = p + 1 } }
103 }
104 f = f + 1
105 }
106 if p >= e { out[0] = 0 as u8; return 0 }
107 var k: i64 = 0
108 while p < e {
109 if buf[p] == (9 as u8) { p = e } else {
110 if k < cap - 1 { out[k] = buf[p]; k = k + 1 }
111 p = p + 1
112 }
113 }
114 out[k] = 0 as u8
115 return k
116}
117
118// parse unsigned digits from s starting at pi[0]; advances pi past them. 0 if none.
119func w_atoi(s: *u8, pi: *i64) -> i64 {
120 var i: i64 = pi[0]
121 var v: i64 = 0
122 var run: i64 = 1
123 while run == 1 {
124 if s[i] < (48 as u8) { run = 0 } else {
125 if s[i] > (57 as u8) { run = 0 } else { v = v*10 + ((s[i] as i64) - 48); i = i + 1 }
126 }
127 }
128 pi[0] = i
129 return v
130}
131
132// look up a mode row -> register/lane/structure (+ optional col5 max_tokens, col6 arc).
133// Old 5-column rows stay valid: missing fields come back empty -> caller defaults. 1 = found.
134func w_mode_lookup(mode: *u8, reg: *u8, lane: *u8, structure: *u8, mtok: *u8, arc: *u8) -> i64 {
135 let buf: *u8 = sys_mmap(W_BUF)
136 let n: i64 = sts_load(W_PLANE, buf, W_BUF)
137 if n <= 0 { return 0 - 1 }
138 let nm: *u8 = sys_mmap(128)
139 var p: i64 = 0
140 while p < n {
141 var e: i64 = n
142 var q: i64 = p
143 var go: i64 = 1
144 while go == 1 {
145 if q >= n { e = n; go = 0 } else { if buf[q] == (10 as u8) { e = q; go = 0 } else { q = q + 1 } }
146 }
147 if e > p {
148 if buf[p] != (35 as u8) { // skip comments
149 w_field(buf, p, e, 0, nm, 128)
150 if w_streq(nm, mode) == 1 {
151 w_field(buf, p, e, 1, reg, 64)
152 w_field(buf, p, e, 2, lane, 64)
153 w_field(buf, p, e, 3, structure, 64)
154 w_field(buf, p, e, 5, mtok, 16)
155 w_field(buf, p, e, 6, arc, 16)
156 return 1
157 }
158 }
159 }
160 p = e + 1
161 }
162 return 0
163}
164
165func w_list_modes() -> i64 {
166 let buf: *u8 = sys_mmap(W_BUF)
167 let n: i64 = sts_load(W_PLANE, buf, W_BUF)
168 if n <= 0 { we("nx_write: writemode- plane unseeded -- run `nx_write migrate` once\n\x00" as *u8); return 1 }
169 ww("# writemode- plane (SSOT; columns: mode register lane structure description [max_tokens] [arc])\n" as *u8)
170 sys_write(1, buf, n)
171 return 0
172}
173
174// one-time (re)seed: read the tombstoned tsv, keep DATA rows only, sts_seed the plane, report parity.
175func w_migrate() -> i64 {
176 let raw: *u8 = sys_mmap(W_BUF)
177 let n: i64 = w_slurp("knowledge/registry/write_modes.tsv" as *u8, raw, W_BUF)
178 if n <= 0 { we("nx_write migrate: write_modes.tsv unreadable\n\x00" as *u8); return 1 }
179 let clean: *u8 = sys_mmap(W_BUF)
180 var co: i64 = 0
181 var tsvrows: i64 = 0
182 var p: i64 = 0
183 while p < n {
184 var e: i64 = p
185 var go: i64 = 1
186 while go == 1 {
187 if e >= n { go = 0 } else { if raw[e] == (10 as u8) { go = 0 } else { e = e + 1 } }
188 }
189 if e > p { if raw[p] != (35 as u8) {
190 var q: i64 = p
191 while q < e { clean[co] = raw[q]; co = co + 1; q = q + 1 }
192 clean[co] = 10 as u8; co = co + 1
193 tsvrows = tsvrows + 1
194 } }
195 p = e + 1
196 }
197 let seeded: i64 = sts_seed(W_PLANE, clean, co)
198 ww("WRITEMODE-MIGRATE tsv_rows=" as *u8)
199 let nb: *u8 = sys_mmap(32)
200 var nn: i64 = w_catn(nb, 0, tsvrows)
201 sys_write(1, nb, nn)
202 ww(" plane_rows=" as *u8)
203 nn = w_catn(nb, 0, seeded)
204 sys_write(1, nb, nn)
205 if seeded == tsvrows { ww(" PARITY-OK (plane is now the SSOT; tsv is a tombstone)\n" as *u8); return 0 }
206 ww(" PARITY-FAIL -- do not tombstone, investigate\n" as *u8)
207 return 1
208}
209
210// system prompt per STRUCTURE -- the registry's own column drives it, so adding a mode is a row edit.
211// arc column: "complete" = carry the piece through its FULL arc (the fade-out class: a scene prompt
212// that says "end on a beat that invites what comes next" plus a token ceiling reads as coy
213// truncation -- for modes that declare complete, the ending is part of the deliverable).
214func w_system_for(structure: *u8, arc: *u8, out: *u8) -> i64 {
215 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)
216 if w_streq(structure, "scene" as *u8) == 1 {
217 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)
218 } else { if w_streq(structure, "scenario" as *u8) == 1 {
219 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)
220 } else { if w_streq(structure, "panel" as *u8) == 1 {
221 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)
222 } else { if w_streq(structure, "tone" as *u8) == 1 {
223 o = w_cat(out, o, "Match the requested voice closely. Keep sentence rhythm and diction consistent throughout." as *u8)
224 } else { if w_streq(structure, "imrad" as *u8) == 1 {
225 o = w_cat(out, o, "Use IMRaD structure: Introduction, Methods, Results, Discussion. Be precise and cite nothing you cannot support." as *u8)
226 } else { if w_streq(structure, "convo" as *u8) == 1 {
227 o = w_cat(out, o, "Write a natural back-and-forth conversation that keeps the topic moving." as *u8)
228 } else {
229 o = w_cat(out, o, "Write clearly and vividly in the form the request implies." as *u8)
230 } } } } } }
231 if w_streq(arc, "complete" as *u8) == 1 {
232 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)
233 }
234 out[o] = 0 as u8
235 return o
236}
237
238// POST /v1/chat/completions to a.b.c.d:port; response into resp. returns length, -1 on failure.
239func w_engine_call(a: i64, b: i64, c: i64, d: i64, port: i64, req: *u8, reqlen: i64, resp: *u8, cap: i64) -> i64 {
240 let fd: i64 = sys_socket(2, 1, 0)
241 if fd < 0 { return 0 - 1 }
242 sys_set_socket_timeout(fd, W_TMO_SEC)
243 let sa: *u8 = sys_mmap(16)
244 sa[0] = 2 as u8; sa[1] = 0 as u8
245 sa[2] = ((port >> 8) & 0xff) as u8; sa[3] = (port & 0xff) as u8
246 sa[4] = a as u8; sa[5] = b as u8; sa[6] = c as u8; sa[7] = d as u8
247 var z: i64 = 8
248 while z < 16 { sa[z] = 0 as u8; z = z + 1 }
249 if nx_connect_bounded(fd, sa, 16, NX_CONN_DEFAULT_MS) != 0 { sys_close(fd); return 0 - 1 }
250 sys_write(fd, req, reqlen)
251 var t: i64 = 0
252 var r: i64 = 1
253 while r > 0 {
254 if t >= cap { r = 0 } else { r = sys_read(fd, ((resp as i64) + t) as *u8, cap - t); if r > 0 { t = t + r } }
255 }
256 sys_close(fd)
257 return t
258}
259
260// try-connect only: 0 = reachable, nonzero = not. Bounded like every other connect here, so an
261// absent/firewalled brain costs one connect window, never a read timeout.
262func w_probe(a: i64, b: i64, c: i64, d: i64, port: i64) -> i64 {
263 let fd: i64 = sys_socket(2, 1, 0)
264 if fd < 0 { return 0 - 1 }
265 let sa: *u8 = sys_mmap(16)
266 sa[0] = 2 as u8; sa[1] = 0 as u8
267 sa[2] = ((port >> 8) & 0xff) as u8; sa[3] = (port & 0xff) as u8
268 sa[4] = a as u8; sa[5] = b as u8; sa[6] = c as u8; sa[7] = d as u8
269 var z: i64 = 8
270 while z < 16 { sa[z] = 0 as u8; z = z + 1 }
271 let rc: i64 = nx_connect_bounded(fd, sa, 16, NX_CONN_DEFAULT_MS)
272 sys_close(fd)
273 if rc != 0 { return 0 - 1 }
274 return 0
275}
276
277// pull the assistant text out of {"choices":[{"message":{"content":"..."}}]} and unescape it.
278func w_extract(resp: *u8, n: i64) -> i64 {
279 let key: *u8 = "\"content\":\"" as *u8
280 let kl: i64 = w_len(key)
281 var i: i64 = 0
282 var s: i64 = 0 - 1
283 while i + kl <= n {
284 var j: i64 = 0
285 var same: i64 = 1
286 while j < kl { if resp[i + j] != key[j] { same = 0; j = kl } else { j = j + 1 } }
287 if same == 1 { s = i + kl; i = n } else { i = i + 1 }
288 }
289 if s < 0 { return 0 - 1 }
290 let out: *u8 = sys_mmap(W_BUF)
291 var o: i64 = 0
292 var p: i64 = s
293 var go: i64 = 1
294 while go == 1 {
295 if p >= n { go = 0 } else {
296 let ch: i64 = resp[p] & 0xff
297 if ch == 34 { go = 0 }
298 else {
299 if ch == 92 {
300 let nx: i64 = resp[p + 1] & 0xff
301 if nx == 110 { out[o] = 10 as u8; o = o + 1; p = p + 2 }
302 else { if nx == 116 { out[o] = 9 as u8; o = o + 1; p = p + 2 }
303 else { out[o] = resp[p + 1]; o = o + 1; p = p + 2 } }
304 } else { out[o] = resp[p]; o = o + 1; p = p + 1 }
305 }
306 }
307 }
308 sys_write(1, out, o)
309 ww("\n\x00" as *u8)
310 return o
311}
312
313// parse "a.b.c.d:port" into w[0..4]; 1 = ok
314func w_parse_addr(s: *u8, w: *i64) -> i64 {
315 var i: i64 = 0
316 var f: i64 = 0
317 while f < 5 {
318 var v: i64 = 0
319 var dig: i64 = 0
320 var scan: i64 = 1
321 while scan == 1 {
322 let c: i64 = s[i] as i64
323 if c < 48 { scan = 0 } else { if c > 57 { scan = 0 } else { v = v * 10 + (c - 48); dig = dig + 1; i = i + 1 } }
324 }
325 if dig == 0 { return 0 }
326 w[f] = v
327 f = f + 1
328 if f < 5 { i = i + 1 } // skip the '.' or ':'
329 }
330 return 1
331}
332
333func main(argc: i64, argv: *i64) -> i64 {
334 ep_anchor()
335 if argc < 2 {
336 ww("usage: nx_write <mode> <prompt...> | nx_write modes\n\x00" as *u8)
337 return 1
338 }
339 let mode: *u8 = argv[1] as *u8
340 if w_streq(mode, "modes" as *u8) == 1 { return w_list_modes() }
341 if w_streq(mode, "migrate" as *u8) == 1 { return w_migrate() }
342 if argc < 3 { we("nx_write: needs a prompt\n\x00" as *u8); return 2 }
343
344 let reg: *u8 = sys_mmap(64)
345 let lane: *u8 = sys_mmap(64)
346 let structure: *u8 = sys_mmap(64)
347 let mtok: *u8 = sys_mmap(16)
348 let arc: *u8 = sys_mmap(16)
349 let found: i64 = w_mode_lookup(mode, reg, lane, structure, mtok, arc)
350 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 }
351 if found == 0 {
352 we("nx_write: unknown mode -- run `nx_write modes` for the registry\n\x00" as *u8)
353 return 4
354 }
355
356 // u2605THE SEAM, CHECKED BEFORE A BYTE IS SENT: an explicit register may only run on the local lane.
357 if w_streq(reg, "explicit" as *u8) == 1 {
358 if w_streq(lane, "local" as *u8) == 0 {
359 we("nx_write REFUSED: mode is register=explicit but lane=\x00" as *u8); we(lane)
360 we(" -- an explicit register may only run on the local lane. Fix the registry row, not this call.\n\x00" as *u8)
361 return 5
362 }
363 }
364
365 // SPOKE-YIELD ADMISSION (operator 2026-08-05): if the spoke's sentinel reports an interactive
366 // GPU tenant (a game), the swarm YIELDS -- interactive sessions outrank batch generation. The
367 // hub is not brought down and nothing is lost: the writer's async lane keeps the request as a
368 // durable .req and the sweeper runs it when the GPU frees. Conf-driven (gpu_yield_to_games).
369 if lc_write_lane("gpu_yield_to_games" as *u8, 1) == 1 {
370 let gb: *u8 = sys_mmap(256)
371 let gn: i64 = w_slurp("knowledge/status/gpu_avail.conf" as *u8, gb, 250)
372 if gn > 0 {
373 let gp: *i64 = sys_mmap(16) as *i64
374 gp[0] = 0
375 let gep: i64 = w_atoi(gb, gp)
376 let nowt: *i64 = sys_mmap(16) as *i64
377 nowt[0] = 0
378 sys_clock_gettime_real(nowt)
379 if nowt[0] - gep < lc_write_lane("gpu_avail_max_age_sec" as *u8, 180) {
380 var gi: i64 = 0
381 var isgame: i64 = 0
382 while gi + 5 < gn {
383 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) {
384 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 } } } }
385 if isgame == 0 { isgame = 1 }
386 gi = gn
387 } } } } }
388 gi = gi + 1
389 }
390 if isgame == 1 {
391 ww("NX-WRITE-DEFERRED gpu yielded to interactive session (sentinel: game present); queued jobs run when the gpu frees\n" as *u8)
392 return 0
393 }
394 }
395 }
396 }
397
398 // endpoint from the swarm SSOT -- prefer the dedicated write brain (gpu-write, llama-server),
399 // fall back to the image engine's chat lane (gpu-image). Both rows live in knowledge/swarm_nodes.conf;
400 // adding/moving a brain is a ROW EDIT, never a code edit. u2605RESOLVE IS NOT REACHABLE (the swarm
401 // co_usable lesson): the preferred role must also PROBE-CONNECT, else a firewalled brain wedges
402 // the lane that a healthy fallback could serve.
403 var addr: *u8 = se_addr("gpu-write" as *u8)
404 if (addr as i64) != 0 {
405 let wp: *i64 = sys_mmap(64) as *i64
406 if w_parse_addr(addr, wp) == 1 {
407 if w_probe(wp[0], wp[1], wp[2], wp[3], wp[4]) != 0 { addr = 0 as *u8 }
408 } else { addr = 0 as *u8 }
409 }
410 if (addr as i64) == 0 { addr = se_addr("gpu-image" as *u8) }
411 if (addr as i64) == 0 {
412 we("nx_write: neither gpu-write nor gpu-image resolvable in knowledge/swarm_nodes.conf (fail-closed; no fabricated endpoint)\n\x00" as *u8)
413 return 6
414 }
415 let w4: *i64 = sys_mmap(64) as *i64
416 if w_parse_addr(addr, w4) == 0 { we("nx_write: malformed endpoint row\n\x00" as *u8); return 6 }
417
418 // length: registry col5 (per mode) -> conf default; a leading len=<N> prompt token
419 // overrides per call, clamped to the conf min/max.
420 var toks: i64 = lc_write_lane("write_default_max_tokens" as *u8, W_MAXTOK)
421 let lmin: i64 = lc_write_lane("write_len_min" as *u8, W_LEN_MIN)
422 let lmax: i64 = lc_write_lane("write_len_max" as *u8, W_LEN_MAX)
423 if mtok[0] != (0 as u8) {
424 let mp: *i64 = sys_mmap(16) as *i64
425 mp[0] = 0
426 let mv: i64 = w_atoi(mtok, mp)
427 if mv > 0 { toks = mv }
428 }
429 // len=<N> may arrive as its OWN argv token (CLI) or as the PREFIX of a single prompt string
430 // (the /write daemon passes the whole body as one arg) -- handle both.
431 var ai: i64 = 2
432 var a2off: i64 = 0
433 let a2: *u8 = argv[2] as *u8
434 if a2[0] == (108 as u8) { if a2[1] == (101 as u8) { if a2[2] == (110 as u8) { if a2[3] == (61 as u8) {
435 let lp: *i64 = sys_mmap(16) as *i64
436 lp[0] = 4
437 let lv: i64 = w_atoi(a2, lp)
438 if lv >= lmin { if lv <= lmax {
439 toks = lv
440 if a2[lp[0]] == (0 as u8) { ai = 3 } else {
441 if a2[lp[0]] == (32 as u8) { a2off = lp[0] + 1 }
442 }
443 } }
444 } } } }
445 if ai >= argc { if a2off == 0 { we("nx_write: needs a prompt after len=\n\x00" as *u8); return 2 } }
446
447 // assemble the prompt from argv[ai..] (a2off skips a consumed len= prefix inside argv[2])
448 let user: *u8 = sys_mmap(W_REQ)
449 var uo: i64 = 0
450 while ai < argc {
451 if uo > 0 { user[uo] = 32 as u8; uo = uo + 1 }
452 if ai == 2 { uo = w_cat(user, uo, ((a2 as i64) + a2off) as *u8) } else { uo = w_cat(user, uo, argv[ai] as *u8) }
453 ai = ai + 1
454 }
455 user[uo] = 0 as u8
456
457 let sysp: *u8 = sys_mmap(W_MAGIC_4096)
458 w_system_for(structure, arc, sysp)
459
460 let body: *u8 = sys_mmap(W_REQ)
461 var bo: i64 = w_cat(body, 0, "{\"model\":\"local\",\"max_tokens\":" as *u8)
462 bo = w_catn(body, bo, toks)
463 bo = w_cat(body, bo, ",\"messages\":[{\"role\":\"system\",\"content\":\"" as *u8)
464 bo = w_jesc(body, bo, sysp)
465 bo = w_cat(body, bo, "\"},{\"role\":\"user\",\"content\":\"" as *u8)
466 bo = w_jesc(body, bo, user)
467 bo = w_cat(body, bo, "\"}]}" as *u8)
468
469 let req: *u8 = sys_mmap(W_REQ)
470 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)
471 ro = w_catn(req, ro, bo)
472 ro = w_cat(req, ro, "\r\n\r\n" as *u8)
473 var bi: i64 = 0
474 while bi < bo { req[ro] = body[bi]; ro = ro + 1; bi = bi + 1 }
475
476 let resp: *u8 = sys_mmap(W_BUF)
477 let rn: i64 = w_engine_call(w4[0], w4[1], w4[2], w4[3], w4[4], req, ro, resp, W_BUF)
478 if rn <= 0 {
479 we("nx_write: engine unreachable at \x00" as *u8); we(addr)
480 we(" -- is the local engine up? (nishi_elara_engine_keeper.ps1)\n\x00" as *u8)
481 return 7
482 }
483 if w_extract(resp, rn) < 0 {
484 we("nx_write: engine replied but no content field -- raw response follows on stderr\n\x00" as *u8)
485 sys_write(2, resp, rn)
486 return 8
487 }
488 return 0
489}