code wiki / (root) / nx_forge_model.nx

nx_forge_model.nx source

↩ module page · 285 lines · 11419 B

1// nx_forge_model.nx -- FORGE F3 rung 2: the MODEL BACKEND for the driver. Turns a model serve's 2// HTTP /gen response into a candidate .nx file, and composes the prompt the model sees. Same loop 3// as rung 1 -- the backend just PRODUCES the candidate that fg_run then judges byte-exact. 4// fm_compose_prompt(pack, task, repair, out, cap) pack v1 + task statement + (optional) the 5// verbatim repair context from a prior failed cycle -> prompt file. 6// fm_build_gen_body(prompt, plen, max_new, mode, out) the serve's POST /gen JSON body. 7// fm_post_gen(a,b,c,d, port, body, blen, resp, rescap) TCP POST /gen to a.b.c.d:port over the 8// proven nx_http_client primitives; returns response bytes (header+body). 9// fm_extract_text(resp, rlen, out, cap) pull the JSON "text" value, unescaping \n \t \" \\ \/ 10// \r and \uXXXX (low byte) -> the raw model output. -1 if absent. 11// fm_strip_fences(src, n, out) drop a leading ```lang fence line + trailing ``` (the pilot's 12// hand extraction stage, now an organ). Idempotent on unfenced text. 13// fm_stub_serve_once(port, respfile) an in-process single-shot serve (gate fixture): binds, 14// accepts one client, replies with respfile's bytes as a /gen JSON -> lets 15// the gate prove the REAL loopback round-trip with no external model. 16// Rung 2 proves the model-stage mechanics sovereignly; pointing fm_post_gen at 127.0.0.1:11434 17// (the no-float serve) or an API egress is a live address swap, not new logic. 18// license_tier: ORIGINAL 19import "nx_forge.nx" 20import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host 21import "nx_http_client.nx" 22 23func fm_hexval(c: i64) -> i64 { 24 if c >= 48 && c <= 57 { return c - 48 } 25 if c >= 97 && c <= 102 { return c - 97 + 10 } 26 if c >= 65 && c <= 70 { return c - 65 + 10 } 27 return 0 28} 29 30// compose the model prompt: pack v1 + task + optional repair context. Returns length (-1 on fail). 31func fm_compose_prompt(packpath: *u8, task: *u8, repairpath: *u8, out: *u8, cap: i64) -> i64 { 32 let pn: i64 = fc_read(packpath, out, cap) 33 if pn <= 0 { return 0 - 1 } 34 var o: i64 = pn 35 let h: *u8 = "\n\nTASK\n----\n" as *u8 36 var i: i64 = 0 37 while h[i] != (0 as u8) { out[o] = h[i]; o = o + 1; i = i + 1 } 38 i = 0 39 while task[i] != (0 as u8) { 40 if o >= cap { return 0 - 1 } 41 out[o] = task[i] 42 o = o + 1 43 i = i + 1 44 } 45 if (repairpath as i64) != 0 { 46 let rfd: i64 = sys_openat_rd(repairpath) 47 if rfd >= 0 { 48 let hh: *u8 = "\n\nPRIOR ATTEMPT FAILED -- the sovereign toolchain reported (fix exactly this, stay in the verified subset):\n" as *u8 49 var j: i64 = 0 50 while hh[j] != (0 as u8) { out[o] = hh[j]; o = o + 1; j = j + 1 } 51 var go: i64 = 1 52 while go == 1 { 53 let room: i64 = cap - o 54 if room <= 1 { go = 0 } 55 if go == 1 { 56 let p: *u8 = out + o 57 let r: i64 = sys_read(rfd, p, room) 58 if r <= 0 { go = 0 } 59 if r > 0 { o = o + r } 60 } 61 } 62 sys_close(rfd) 63 } 64 } 65 out[o] = 0 as u8 66 return o 67} 68 69// JSON body for POST /gen. mode 0=i32 (lossless), 1=i8 (fast). 70func fm_build_gen_body(prompt: *u8, plen: i64, max_new: i64, mode: i64, out: *u8) -> i64 { 71 var o: i64 = 0 72 let a: *u8 = "{\"prompt\":\"" as *u8 73 var i: i64 = 0 74 while a[i] != (0 as u8) { out[o] = a[i]; o = o + 1; i = i + 1 } 75 o = fc_json_esc_bytes(out, o, prompt, plen) 76 let b: *u8 = "\",\"max_new\":" as *u8 77 i = 0 78 while b[i] != (0 as u8) { out[o] = b[i]; o = o + 1; i = i + 1 } 79 let ml: i64 = std_itoa(max_new, out + o) 80 o = o + ml 81 let c: *u8 = ",\"mode\":" as *u8 82 i = 0 83 while c[i] != (0 as u8) { out[o] = c[i]; o = o + 1; i = i + 1 } 84 let mdl: i64 = std_itoa(mode, out + o) 85 o = o + mdl 86 out[o] = 125 as u8 87 o = o + 1 88 return o 89} 90 91// minimal JSON string-escape of src[0,n) into dst at off (", \, newline, tab, CR) 92func fc_json_esc_bytes(dst: *u8, off: i64, src: *u8, n: i64) -> i64 { 93 var o: i64 = off 94 var i: i64 = 0 95 while i < n { 96 let c: i64 = src[i] as i64 97 if c == 34 { dst[o] = 92 as u8; o = o + 1; dst[o] = 34 as u8; o = o + 1 } 98 if c == 92 { dst[o] = 92 as u8; o = o + 1; dst[o] = 92 as u8; o = o + 1 } 99 if c == 10 { dst[o] = 92 as u8; o = o + 1; dst[o] = 110 as u8; o = o + 1 } 100 if c == 9 { dst[o] = 92 as u8; o = o + 1; dst[o] = 116 as u8; o = o + 1 } 101 if c == 13 { dst[o] = 92 as u8; o = o + 1; dst[o] = 114 as u8; o = o + 1 } 102 if c != 34 && c != 92 && c != 10 && c != 9 && c != 13 { dst[o] = c as u8; o = o + 1 } 103 i = i + 1 104 } 105 return o 106} 107 108// find the JSON "text":" value and unescape it into out; returns len or -1 109func fm_extract_text(resp: *u8, rlen: i64, out: *u8, cap: i64) -> i64 { 110 let key: *u8 = "\"text\":\"" as *u8 111 let kl: i64 = std_slen(key) 112 var start: i64 = 0 - 1 113 var i: i64 = 0 114 let stop: i64 = rlen - kl 115 while i <= stop { 116 var j: i64 = 0 117 var hit: i64 = 1 118 while j < kl { 119 let idx: i64 = i + j 120 let a: i64 = resp[idx] as i64 121 let b: i64 = key[j] as i64 122 if a != b { hit = 0; j = kl } 123 if a == b { j = j + 1 } 124 } 125 if hit == 1 { start = i + kl; i = stop + 1 } 126 if hit == 0 { i = i + 1 } 127 } 128 if start < 0 { return 0 - 1 } 129 var o: i64 = 0 130 var p: i64 = start 131 var go: i64 = 1 132 while go == 1 { 133 if p >= rlen { go = 0 } 134 if o >= cap { go = 0 } 135 if go == 1 { 136 let c: i64 = resp[p] as i64 137 if c == 34 { go = 0 } 138 if c == 92 { 139 let p1: i64 = p + 1 140 if p1 < rlen { 141 let e: i64 = resp[p1] as i64 142 if e == 110 { out[o] = 10 as u8; o = o + 1; p = p + 2 } 143 if e == 116 { out[o] = 9 as u8; o = o + 1; p = p + 2 } 144 if e == 114 { out[o] = 13 as u8; o = o + 1; p = p + 2 } 145 if e == 34 { out[o] = 34 as u8; o = o + 1; p = p + 2 } 146 if e == 92 { out[o] = 92 as u8; o = o + 1; p = p + 2 } 147 if e == 47 { out[o] = 47 as u8; o = o + 1; p = p + 2 } 148 if e == 117 { 149 let h3: i64 = p + 5 150 if h3 < rlen { 151 let d0: i64 = fm_hexval(resp[p + 2] as i64) 152 let d1: i64 = fm_hexval(resp[p + 3] as i64) 153 let d2: i64 = fm_hexval(resp[p + 4] as i64) 154 let d3: i64 = fm_hexval(resp[p + 5] as i64) 155 let hi: i64 = d0 * 4096 + d1 * 256 + d2 * 16 + d3 156 out[o] = (hi % 256) as u8 157 o = o + 1 158 p = p + 6 159 } 160 if h3 >= rlen { go = 0 } 161 } 162 if e != 110 && e != 116 && e != 114 && e != 34 && e != 92 && e != 47 && e != 117 { 163 out[o] = e as u8 164 o = o + 1 165 p = p + 2 166 } 167 } 168 if p1 >= rlen { go = 0 } 169 } 170 if c != 34 && c != 92 { 171 out[o] = c as u8 172 o = o + 1 173 p = p + 1 174 } 175 } 176 } 177 out[o] = 0 as u8 178 return o 179} 180 181// strip a leading ```lang fence and the trailing ```; idempotent on unfenced text. Returns len. 182func fm_strip_fences(src: *u8, n: i64, out: *u8) -> i64 { 183 // find first ``` 184 var f0: i64 = 0 - 1 185 var i: i64 = 0 186 let stop: i64 = n - 3 187 while i <= stop { 188 let c0: i64 = src[i] as i64 189 let c1: i64 = src[i + 1] as i64 190 let c2: i64 = src[i + 2] as i64 191 if c0 == 96 && c1 == 96 && c2 == 96 { f0 = i; i = stop + 1 } 192 if f0 < 0 { i = i + 1 } 193 } 194 if f0 < 0 { 195 var k: i64 = 0 196 while k < n { out[k] = src[k]; k = k + 1 } 197 out[n] = 0 as u8 198 return n 199 } 200 // content starts after the newline following the opening fence 201 var cs: i64 = f0 + 3 202 var sc: i64 = 1 203 while sc == 1 { 204 if cs >= n { sc = 0 } 205 if sc == 1 { 206 let c: i64 = src[cs] as i64 207 cs = cs + 1 208 if c == 10 { sc = 0 } 209 } 210 } 211 // find last ``` at or after cs 212 var f1: i64 = n 213 var j: i64 = cs 214 let stop2: i64 = n - 3 215 while j <= stop2 { 216 let d0: i64 = src[j] as i64 217 let d1: i64 = src[j + 1] as i64 218 let d2: i64 = src[j + 2] as i64 219 if d0 == 96 && d1 == 96 && d2 == 96 { f1 = j } 220 j = j + 1 221 } 222 var o: i64 = 0 223 var p: i64 = cs 224 while p < f1 { out[o] = src[p]; o = o + 1; p = p + 1 } 225 out[o] = 0 as u8 226 return o 227} 228 229// TCP POST /gen to a.b.c.d:port with body; response (header+body) into resp. Returns bytes (-1 err). 230func fm_post_gen(a: i64, b: i64, c: i64, d: i64, port: i64, body: *u8, blen: i64, resp: *u8, rescap: i64) -> i64 { 231 let fd: i64 = sys_socket(2, 1, 0) 232 if fd < 0 { return 0 - 1 } 233 let addr: *u8 = sys_mmap(16) as *u8 234 nx_http_client_sockaddr_ipv4(addr, a, b, c, d, port) 235 let cr: i64 = nx_connect_bounded(fd, addr, 16, NX_CONN_DEFAULT_MS) 236 if cr < 0 { sys_close(fd); return 0 - 1 } 237 let req: *u8 = sys_mmap(262144) as *u8 238 let host: *u8 = "127.0.0.1" as *u8 239 let ct: *u8 = "application/json" as *u8 240 let rl: i64 = nx_http_client_build_request_post("/gen" as *u8, 4, host, 9, ct, 16, body, blen, req) 241 let wr: i64 = sys_write(fd, req, rl) 242 if wr != rl { sys_close(fd); return 0 - 1 } 243 let got: i64 = _drain(fd, resp, rescap) 244 sys_close(fd) 245 return got 246} 247 248// in-process single-shot stub serve (gate fixture): reply with respfile bytes as /gen JSON, exit. 249func fm_stub_serve_once(port: i64, respfile: *u8) -> i64 { 250 let fd: i64 = sys_socket(2, 1, 0) 251 if fd < 0 { return 0 - 1 } 252 let opt: *i64 = sys_mmap(8) as *i64 253 opt[0] = 1 254 __syscall(54, fd, 1, 2, opt as i64, 4, 0) 255 let addr: *u8 = sys_mmap(16) as *u8 256 addr[0] = 2 as u8 257 addr[1] = 0 as u8 258 addr[2] = ((port >> 8) & 255) as u8 259 addr[3] = (port & 255) as u8 260 var z: i64 = 4 261 while z < 16 { addr[z] = 0 as u8; z = z + 1 } 262 if sys_bind(fd, addr, 16) < 0 { sys_close(fd); return 0 - 2 } 263 if sys_listen(fd, 16) < 0 { sys_close(fd); return 0 - 3 } 264 let cfd: i64 = sys_accept(fd) 265 if cfd < 0 { sys_close(fd); return 0 - 4 } 266 let rq: *u8 = sys_mmap(65536) as *u8 267 sys_read(cfd, rq, 65536) 268 let bodybuf: *u8 = sys_mmap(65536) as *u8 269 let bn: i64 = fc_read(respfile, bodybuf, 65536) 270 let hdr: *u8 = sys_mmap(256) as *u8 271 var o: i64 = 0 272 let h1: *u8 = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: " as *u8 273 var i: i64 = 0 274 while h1[i] != (0 as u8) { hdr[o] = h1[i]; o = o + 1; i = i + 1 } 275 let dl: i64 = std_itoa(bn, hdr + o) 276 o = o + dl 277 let h2: *u8 = "\r\nConnection: close\r\n\r\n" as *u8 278 i = 0 279 while h2[i] != (0 as u8) { hdr[o] = h2[i]; o = o + 1; i = i + 1 } 280 sys_write(cfd, hdr, o) 281 sys_write(cfd, bodybuf, bn) 282 sys_close(cfd) 283 sys_close(fd) 284 return bn 285}