@costrict/csc 4.1.3 → 4.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-de1c4k01.js → chunk-09d9cpjk.js} +36 -36
- package/dist/{chunk-enqr3kyr.js → chunk-0hf3xsng.js} +3 -3
- package/dist/{chunk-2rwnq8r3.js → chunk-0q6t0wzt.js} +5 -3
- package/dist/{chunk-6m09ewb8.js → chunk-0y9t47jm.js} +5 -5
- package/dist/{chunk-2wtd2nnx.js → chunk-11ekavk1.js} +38 -38
- package/dist/{chunk-szg14h6b.js → chunk-147vdz44.js} +49 -49
- package/dist/{chunk-bv0937vz.js → chunk-1bdg7mgh.js} +21 -10
- package/dist/{chunk-hna6h2sy.js → chunk-1wee9cv0.js} +12 -12
- package/dist/{chunk-wrfm5ns8.js → chunk-1x52prap.js} +35 -35
- package/dist/{chunk-afjpshp6.js → chunk-1xjaqypa.js} +35 -35
- package/dist/{chunk-ma1npmz3.js → chunk-1zwqxpb6.js} +6 -6
- package/dist/{chunk-fk80zmsm.js → chunk-22ys018y.js} +37 -37
- package/dist/{chunk-6net1b7m.js → chunk-24g5r745.js} +35 -35
- package/dist/{chunk-x6whhhmf.js → chunk-2d21405m.js} +4 -4
- package/dist/{chunk-xe1t7je9.js → chunk-2dfz3jwm.js} +5 -5
- package/dist/{chunk-gnbp2ex1.js → chunk-2grx4b5p.js} +13 -13
- package/dist/{chunk-g0y2wqc9.js → chunk-2gv49qs2.js} +39 -39
- package/dist/{chunk-hncpcgh4.js → chunk-2h1dxajn.js} +36 -36
- package/dist/{chunk-12b1dmsy.js → chunk-2j3jrj2e.js} +2 -2
- package/dist/{chunk-9sb46jc2.js → chunk-2pzzfp72.js} +37 -37
- package/dist/{chunk-e9zp7z0t.js → chunk-2rwde424.js} +35 -35
- package/dist/{chunk-vj1ah8mk.js → chunk-2vgbmtyb.js} +5 -5
- package/dist/{chunk-1xqh8b38.js → chunk-2w6j2m6p.js} +2 -2
- package/dist/{chunk-a512zykt.js → chunk-2y94ygfz.js} +2 -2
- package/dist/{chunk-9pm14s7t.js → chunk-2yw4bwfh.js} +5 -5
- package/dist/{chunk-87gmdz72.js → chunk-35dxmwra.js} +36 -36
- package/dist/{chunk-9erret70.js → chunk-37z2mmbw.js} +4 -4
- package/dist/{chunk-sfngaj10.js → chunk-3c280vpt.js} +36 -36
- package/dist/{chunk-95h6g8r1.js → chunk-3e6dv76a.js} +36 -36
- package/dist/{chunk-w827sfvb.js → chunk-3ft93eyw.js} +5 -5
- package/dist/{chunk-yczmbbg4.js → chunk-3khv1k2r.js} +2 -2
- package/dist/{chunk-1kwh4rt9.js → chunk-3te0naan.js} +35 -35
- package/dist/{chunk-we4qzz9b.js → chunk-3vj11ct8.js} +2 -2
- package/dist/{chunk-zdx8qv35.js → chunk-42jhchth.js} +8 -8
- package/dist/{chunk-4j0hes4t.js → chunk-42r75rph.js} +38 -38
- package/dist/{chunk-qdd9jfj2.js → chunk-4436nyqe.js} +36 -36
- package/dist/{chunk-5zm0sq49.js → chunk-454ty3a9.js} +2 -2
- package/dist/{chunk-8vg1bd0f.js → chunk-47mtpn1d.js} +4 -4
- package/dist/{chunk-qhn757jn.js → chunk-48ggg92j.js} +2 -2
- package/dist/{chunk-rzrgcvgz.js → chunk-49sm91ec.js} +3 -3
- package/dist/{chunk-41ncbfk7.js → chunk-4c1h8w56.js} +3 -3
- package/dist/{chunk-wjck9tc8.js → chunk-4c6gwct4.js} +62 -62
- package/dist/{chunk-z5dnf2z3.js → chunk-4c8r5etf.js} +35 -35
- package/dist/{chunk-w8xchcwf.js → chunk-4hhnec4s.js} +3 -3
- package/dist/{chunk-67r2vsnb.js → chunk-4hvh6etx.js} +44 -44
- package/dist/{chunk-7c000hzx.js → chunk-4ke9brnb.js} +4 -4
- package/dist/{chunk-h73pyq61.js → chunk-4kevnqfd.js} +37 -37
- package/dist/{chunk-1ft26qtp.js → chunk-4m0bjecy.js} +6 -6
- package/dist/{chunk-2a3p5js6.js → chunk-4md0mpss.js} +3 -3
- package/dist/{chunk-aac9pvkc.js → chunk-4mdj278s.js} +36 -36
- package/dist/{chunk-1581ek49.js → chunk-4mzrmt07.js} +2 -2
- package/dist/{chunk-1wbp32a2.js → chunk-4r00fs6b.js} +6 -6
- package/dist/{chunk-eqqv7qtc.js → chunk-4v4ztt55.js} +36 -36
- package/dist/{chunk-27z1rw55.js → chunk-4vvph2sr.js} +44 -44
- package/dist/{chunk-ggk3z1g3.js → chunk-4y2sk1ad.js} +35 -35
- package/dist/{chunk-z8geq3je.js → chunk-4zaverwj.js} +10 -10
- package/dist/{chunk-x7cy7td1.js → chunk-5027cx6v.js} +45 -45
- package/dist/{chunk-fhe671pa.js → chunk-50gyyx3a.js} +3 -3
- package/dist/{chunk-34bgqfbe.js → chunk-548vsr6m.js} +38 -38
- package/dist/{chunk-m65njcyf.js → chunk-5511t18e.js} +2 -2
- package/dist/{chunk-exf4vz7n.js → chunk-55kecgcg.js} +2 -2
- package/dist/{chunk-rkyetd1a.js → chunk-5aqaz23r.js} +5 -5
- package/dist/{chunk-j99qakt7.js → chunk-5ev4k0f2.js} +4 -4
- package/dist/{chunk-3pgyvdwv.js → chunk-5h6ra6a2.js} +22 -22
- package/dist/{chunk-v8cfb8af.js → chunk-5kwvenz7.js} +3 -3
- package/dist/{chunk-zza73g6f.js → chunk-5n1mzppd.js} +41 -41
- package/dist/{chunk-g8s9fpwe.js → chunk-5np2696m.js} +7 -7
- package/dist/{chunk-kbbjfeb8.js → chunk-5s1cmr4k.js} +2 -2
- package/dist/{chunk-qxjmqh24.js → chunk-5thkd3nq.js} +35 -35
- package/dist/{chunk-9rsn4yt6.js → chunk-5vh1p3ky.js} +35 -35
- package/dist/{chunk-c1wyp45k.js → chunk-65ryde7a.js} +3 -3
- package/dist/{chunk-zejhysze.js → chunk-6m26tv8b.js} +6 -6
- package/dist/{chunk-x89ex9j5.js → chunk-6p39g0w8.js} +2 -2
- package/dist/{chunk-dawawmrt.js → chunk-6qk13za3.js} +5 -5
- package/dist/{chunk-j1gz4v4p.js → chunk-6t7858mm.js} +3 -3
- package/dist/{chunk-6aevda19.js → chunk-6tv01x8f.js} +2 -2
- package/dist/{chunk-k11dgc0s.js → chunk-6v5kghc6.js} +36 -36
- package/dist/{chunk-hs2th8g3.js → chunk-72329dq9.js} +2 -2
- package/dist/{chunk-ev6km43x.js → chunk-7249b8sr.js} +3 -3
- package/dist/{chunk-2sn6cptw.js → chunk-73zxzeve.js} +35 -35
- package/dist/{chunk-38bbxmnp.js → chunk-7481a4r2.js} +6 -6
- package/dist/{chunk-jztckegg.js → chunk-75qdw92d.js} +37 -37
- package/dist/{chunk-3q45r03d.js → chunk-7694q43p.js} +37 -37
- package/dist/{chunk-szmk7w9a.js → chunk-7a93vkn3.js} +4 -4
- package/dist/{chunk-1scrfjqs.js → chunk-7c1rj5de.js} +4 -3
- package/dist/{chunk-1afca00r.js → chunk-7m65ry6g.js} +35 -35
- package/dist/{chunk-c83pn20p.js → chunk-7z2162vj.js} +6 -6
- package/dist/{chunk-ejg1fbpe.js → chunk-81j0yjj5.js} +6 -6
- package/dist/{chunk-knfegw0w.js → chunk-82b0zw1g.js} +4 -4
- package/dist/{chunk-g6scdccf.js → chunk-83p7ypqz.js} +36 -36
- package/dist/{chunk-29nazcp2.js → chunk-83y4hwve.js} +157 -157
- package/dist/{chunk-8jts3pe0.js → chunk-84ms4gmg.js} +5 -5
- package/dist/{chunk-b4fx4vxn.js → chunk-887mgrcf.js} +35 -35
- package/dist/{chunk-64d49b68.js → chunk-8c5w8v3y.js} +2 -2
- package/dist/{chunk-chqt7f7d.js → chunk-8es30rt4.js} +93 -93
- package/dist/{chunk-54pa5vhx.js → chunk-8fqwp3m6.js} +39 -39
- package/dist/{chunk-7afnr59b.js → chunk-8kjckc8g.js} +4 -4
- package/dist/{chunk-z4jptgws.js → chunk-8qst0rhx.js} +35 -35
- package/dist/{chunk-ssns39mz.js → chunk-8vb5860k.js} +35 -35
- package/dist/{chunk-f2kzcgtn.js → chunk-8y2wphhe.js} +3 -3
- package/dist/{chunk-1bwth1m8.js → chunk-8ztxv0s8.js} +6 -6
- package/dist/{chunk-9k8yx0w0.js → chunk-90dexk03.js} +35 -35
- package/dist/{chunk-re14cg04.js → chunk-948sac2f.js} +3 -3
- package/dist/{chunk-dqnh8s76.js → chunk-953hv54z.js} +38 -38
- package/dist/{chunk-zyhpq0w1.js → chunk-96012zrd.js} +8 -3
- package/dist/{chunk-drdpdd6v.js → chunk-988v9k0d.js} +36 -36
- package/dist/{chunk-40h1nzvx.js → chunk-9frmefq9.js} +7 -7
- package/dist/{chunk-fgsdh4bh.js → chunk-9jftryb5.js} +5 -5
- package/dist/{chunk-sv2ygw88.js → chunk-9p9k73kh.js} +4 -4
- package/dist/{chunk-503675yy.js → chunk-9q15hsft.js} +2 -2
- package/dist/{chunk-kg0tnk3k.js → chunk-9q98b0yn.js} +12 -10
- package/dist/{chunk-eq2m00r1.js → chunk-9rap9ebg.js} +43 -43
- package/dist/{chunk-1wp8ch0w.js → chunk-9rq3w880.js} +4 -3
- package/dist/{chunk-trgdn5d2.js → chunk-9scfrax2.js} +5 -5
- package/dist/{chunk-fqpw4nmh.js → chunk-9spwqs8d.js} +7 -7
- package/dist/{chunk-3gkd2ce8.js → chunk-9tzsvsnw.js} +4 -4
- package/dist/{chunk-t9vd9a27.js → chunk-9w213qwh.js} +46 -46
- package/dist/{chunk-k1ymwd43.js → chunk-9yneyd6s.js} +2 -2
- package/dist/{chunk-dd7145mg.js → chunk-a0vxkvbn.js} +37 -37
- package/dist/{chunk-h56cr4s7.js → chunk-a3jxa40m.js} +29 -29
- package/dist/{chunk-fd2fe2sy.js → chunk-a5tvkr47.js} +2 -2
- package/dist/{chunk-bataz3kd.js → chunk-a9c2z1wz.js} +8 -8
- package/dist/{chunk-sbxktn56.js → chunk-ab57dtc9.js} +5 -5
- package/dist/{chunk-bdw1d8hb.js → chunk-abcd5j5y.js} +12 -12
- package/dist/{chunk-n573a1jj.js → chunk-ag4g1ggt.js} +2 -2
- package/dist/{chunk-y0fh2ws2.js → chunk-amrphgc8.js} +35 -35
- package/dist/{chunk-55q1ad9d.js → chunk-apr24btq.js} +35 -35
- package/dist/{chunk-2pe5qe8m.js → chunk-attapyb3.js} +37 -37
- package/dist/{chunk-wg8x1gvn.js → chunk-awsqxad3.js} +4 -4
- package/dist/{chunk-f21x038e.js → chunk-axh75nac.js} +6 -6
- package/dist/{chunk-d9m98m2j.js → chunk-b0e59wz3.js} +36 -36
- package/dist/{chunk-htwt452w.js → chunk-b652a6dk.js} +35 -35
- package/dist/{chunk-5cqycyzm.js → chunk-b6n6hjak.js} +41 -41
- package/dist/{chunk-r0v733z9.js → chunk-beyedb98.js} +4 -4
- package/dist/{chunk-yba4kmdt.js → chunk-bh5nrh0k.js} +5 -5
- package/dist/{chunk-6fbvxhan.js → chunk-bjf81kyq.js} +2 -2
- package/dist/{chunk-qf1qbfqr.js → chunk-bpj3247f.js} +341 -42
- package/dist/{chunk-rack8qzm.js → chunk-bq6t381k.js} +6 -6
- package/dist/{chunk-e04svc9b.js → chunk-bqaej1qd.js} +35 -35
- package/dist/{chunk-7f68v4kh.js → chunk-bsx46tp0.js} +38 -38
- package/dist/{chunk-txyc16zw.js → chunk-bvgan6hr.js} +35 -35
- package/dist/{chunk-a3c0fv9c.js → chunk-bxm7c03x.js} +35 -35
- package/dist/{chunk-jf6ty3sq.js → chunk-c742mhq9.js} +37 -37
- package/dist/{chunk-24tykx27.js → chunk-cdxhn1zj.js} +38 -38
- package/dist/{chunk-crwwfxjw.js → chunk-cjmw41yz.js} +2 -2
- package/dist/{chunk-ah7vk286.js → chunk-cky6d5se.js} +36 -36
- package/dist/{chunk-jgmrb358.js → chunk-csdze321.js} +36 -36
- package/dist/{chunk-2jy0g6d9.js → chunk-cw94b6wr.js} +35 -35
- package/dist/{chunk-v2wkrfq1.js → chunk-d06vspmk.js} +35 -35
- package/dist/{chunk-spxn09e1.js → chunk-d28aep53.js} +4 -4
- package/dist/{chunk-6vts91xq.js → chunk-d7t9v7ta.js} +3 -3
- package/dist/{chunk-3epkmqrj.js → chunk-da9tm2qa.js} +6 -6
- package/dist/{chunk-52yfqwtn.js → chunk-dak5jvak.js} +6 -6
- package/dist/{chunk-0efb4c53.js → chunk-dq08hqxs.js} +38 -38
- package/dist/{chunk-xfqwnn4z.js → chunk-drdkvee7.js} +8 -8
- package/dist/{chunk-nm43pwz7.js → chunk-dwmzyeff.js} +37 -37
- package/dist/{chunk-vqyb8p8e.js → chunk-dzkpgn3b.js} +37 -37
- package/dist/{chunk-swhfsn91.js → chunk-e1rckp3d.js} +2 -2
- package/dist/{chunk-sjyhjymb.js → chunk-e29asgnz.js} +4 -4
- package/dist/{chunk-24cf0cqq.js → chunk-e56gbfpf.js} +35 -35
- package/dist/{chunk-75stwnkp.js → chunk-e9e7yh7j.js} +36 -36
- package/dist/{chunk-ph1gx3se.js → chunk-eb9a1naq.js} +36 -36
- package/dist/{chunk-ga7r2n5h.js → chunk-ee23jajz.js} +2 -2
- package/dist/{chunk-5nyvjs4d.js → chunk-egrm3m3a.js} +12 -12
- package/dist/{chunk-52f3aqnq.js → chunk-ehc914vn.js} +11 -4
- package/dist/{chunk-zajaqpf0.js → chunk-ehjsvcrt.js} +5 -5
- package/dist/{chunk-ny8apb46.js → chunk-en9y1v8v.js} +2 -2
- package/dist/{chunk-dvvz9s8v.js → chunk-eqdmywve.js} +35 -35
- package/dist/{chunk-pcm3kg7t.js → chunk-erqvy07y.js} +35 -35
- package/dist/{chunk-e8y3h419.js → chunk-esxjcj0y.js} +40 -40
- package/dist/{chunk-xvmtyz8q.js → chunk-et2dhhdq.js} +2 -2
- package/dist/{chunk-h90x0657.js → chunk-ey3q6r96.js} +35 -35
- package/dist/{chunk-7rhyt52m.js → chunk-eya7mh5s.js} +35 -35
- package/dist/{chunk-jbvw7678.js → chunk-eycktzbk.js} +10 -10
- package/dist/{chunk-xhm4ajh7.js → chunk-ezj1ys56.js} +2 -2
- package/dist/{chunk-qgg3q8tz.js → chunk-f092tjve.js} +35 -35
- package/dist/{chunk-gwp0pv2f.js → chunk-f4bg3n9r.js} +37 -37
- package/dist/{chunk-a4n08tzt.js → chunk-f4d05y69.js} +4 -4
- package/dist/{chunk-gawr1q6c.js → chunk-f6wcbaqd.js} +54 -54
- package/dist/{chunk-wayg0dmc.js → chunk-f9asafa4.js} +9 -9
- package/dist/{chunk-kbxfw81h.js → chunk-f9yqhfrd.js} +3 -3
- package/dist/{chunk-1j6j8n37.js → chunk-fawmw9km.js} +2 -2
- package/dist/{chunk-wt6z412w.js → chunk-fejn0zak.js} +6 -6
- package/dist/{chunk-shk7nvvr.js → chunk-ffpht24v.js} +35 -35
- package/dist/{chunk-2k59dwt9.js → chunk-fm1cnxaj.js} +2 -2
- package/dist/{chunk-37b5w46j.js → chunk-fp9vj0rq.js} +50 -50
- package/dist/{chunk-w7ta03fa.js → chunk-fr6qz9nr.js} +45 -45
- package/dist/{chunk-2b6qg988.js → chunk-fs5cdxnp.js} +7 -7
- package/dist/{chunk-ch3xn14w.js → chunk-fv0k0mn7.js} +2 -2
- package/dist/{chunk-dbdtp6ym.js → chunk-g95zt8k8.js} +36 -36
- package/dist/{chunk-djdd7bk9.js → chunk-g9mdg0wk.js} +4 -4
- package/dist/{chunk-rr5nqmgv.js → chunk-gda7ak8c.js} +42 -42
- package/dist/{chunk-psjzsm7e.js → chunk-gg4ky3pk.js} +37 -37
- package/dist/{chunk-en4g0hk8.js → chunk-gh3sxpqt.js} +2 -2
- package/dist/{chunk-3s8sm6ef.js → chunk-gkfhy27z.js} +2 -2
- package/dist/{chunk-qpaf909v.js → chunk-gkp071jz.js} +6 -6
- package/dist/{chunk-j480p8b8.js → chunk-gmgyqmw4.js} +35 -35
- package/dist/{chunk-vg7c66e1.js → chunk-gxzr8z7f.js} +35 -35
- package/dist/{chunk-r7mwzjrk.js → chunk-h03eymaj.js} +35 -35
- package/dist/{chunk-y5cqv5tc.js → chunk-h145ywcf.js} +35 -35
- package/dist/{chunk-6jg2cm3e.js → chunk-h3gj9h7t.js} +36 -36
- package/dist/{chunk-dyrbt3wv.js → chunk-h4hzqagh.js} +5 -5
- package/dist/{chunk-wqjc95g9.js → chunk-h7meex22.js} +3 -3
- package/dist/{chunk-ch4t4jtk.js → chunk-ha4bgnn1.js} +222 -75
- package/dist/{chunk-10cg8kb6.js → chunk-hf7w6c1y.js} +7 -7
- package/dist/{chunk-f2nvt8fp.js → chunk-hm3c5jch.js} +35 -35
- package/dist/{chunk-52b7ehjh.js → chunk-hrmytevz.js} +5 -5
- package/dist/{chunk-drt7fjmp.js → chunk-hw7zdnaq.js} +5 -5
- package/dist/{chunk-7qewvs3p.js → chunk-hz3rdc5x.js} +7 -7
- package/dist/{chunk-8d3a6p31.js → chunk-hzyn43j3.js} +36 -36
- package/dist/{chunk-z9t53qpz.js → chunk-j1esynw3.js} +6 -6
- package/dist/{chunk-e195kh9k.js → chunk-j20g74f9.js} +7 -7
- package/dist/{chunk-5kzdgkdj.js → chunk-j9xne3kv.js} +5 -5
- package/dist/{chunk-m0162q7p.js → chunk-jcjyq2p1.js} +6 -6
- package/dist/{chunk-qf2sxfvx.js → chunk-jcykmnmk.js} +4 -4
- package/dist/{chunk-zbdv3z8q.js → chunk-jdx6pqay.js} +709 -322
- package/dist/{chunk-xvwwssss.js → chunk-jm3bfch2.js} +35 -35
- package/dist/{chunk-sm2b4yze.js → chunk-js2a5x6x.js} +2 -2
- package/dist/{chunk-4b7qt71s.js → chunk-jw0j8e2k.js} +6 -6
- package/dist/{chunk-kpzk32ty.js → chunk-jx52c20q.js} +35 -35
- package/dist/{chunk-cznpjmse.js → chunk-k5a0g0n1.js} +2 -2
- package/dist/{chunk-9eq41w6b.js → chunk-kbm6tqp9.js} +38 -38
- package/dist/{chunk-cwc21b40.js → chunk-ke8xk8zg.js} +3 -3
- package/dist/{chunk-nq1rsvfz.js → chunk-khwgvhnp.js} +40 -40
- package/dist/{chunk-gajcnx28.js → chunk-kp1y42ya.js} +36 -36
- package/dist/chunk-ksav9jw1.js +2118 -0
- package/dist/{chunk-1ym25c4e.js → chunk-ky133fvv.js} +6 -6
- package/dist/{chunk-j2zze00k.js → chunk-kz68xhzh.js} +5 -5
- package/dist/{chunk-676tz9h4.js → chunk-m0fnkcdr.js} +6 -6
- package/dist/{chunk-2vwzpmf1.js → chunk-m1q1cs5y.js} +38 -38
- package/dist/{chunk-ngxhjzcg.js → chunk-m2t05hdr.js} +3 -3
- package/dist/{chunk-q72dtjqy.js → chunk-m4bfhf56.js} +2 -2
- package/dist/{chunk-5ejqdjxh.js → chunk-mb7ne7fv.js} +2 -2
- package/dist/{chunk-tzvq7rxy.js → chunk-mn3rbfas.js} +38 -38
- package/dist/{chunk-29e3th58.js → chunk-mne7ewfn.js} +41 -41
- package/dist/{chunk-xrnq71ar.js → chunk-mqfdx9c1.js} +5 -5
- package/dist/{chunk-kdk3mf2v.js → chunk-mwzga09f.js} +6 -6
- package/dist/{chunk-f9vj65e1.js → chunk-my2v9ayn.js} +2 -2
- package/dist/{chunk-y3cshvgb.js → chunk-mzbwfkxd.js} +2 -2
- package/dist/{chunk-xy8fvtmc.js → chunk-mzv3b466.js} +4 -4
- package/dist/{chunk-t2y20xst.js → chunk-n3mpdn3c.js} +3 -3
- package/dist/{chunk-f5v8s90v.js → chunk-n57j5gs3.js} +42 -42
- package/dist/{chunk-egddfaxd.js → chunk-n7za733h.js} +9 -9
- package/dist/{chunk-v4hnp7jz.js → chunk-n7zfvhh2.js} +46 -46
- package/dist/{chunk-c2vcqqd0.js → chunk-n89tc6qq.js} +6 -6
- package/dist/{chunk-hc0zk8tk.js → chunk-n8jjg228.js} +3 -3
- package/dist/{chunk-46gs9bda.js → chunk-nk786fyz.js} +36 -36
- package/dist/{chunk-ctby762y.js → chunk-nqm0yexv.js} +35 -35
- package/dist/{chunk-652wyftm.js → chunk-nx8c61ax.js} +3 -3
- package/dist/{chunk-t8w1k5ze.js → chunk-nxfeyrc7.js} +35 -35
- package/dist/{chunk-hkzbx2wm.js → chunk-p1m1w5dz.js} +12 -7
- package/dist/{chunk-kj4am4dt.js → chunk-p1phzye5.js} +3 -3
- package/dist/{chunk-v0ps90qx.js → chunk-p41t988k.js} +35 -35
- package/dist/{chunk-w6c96t1t.js → chunk-p4ymzqkv.js} +2 -2
- package/dist/{chunk-j3q9ex7c.js → chunk-p5dfmkjr.js} +6 -6
- package/dist/{chunk-cn1gsn85.js → chunk-p6r9kbzs.js} +2 -2
- package/dist/{chunk-mvp6973m.js → chunk-p6v3r3ft.js} +3 -3
- package/dist/{chunk-121s36ee.js → chunk-pbsv26se.js} +35 -35
- package/dist/{chunk-zawttmz4.js → chunk-pfza1h60.js} +38 -38
- package/dist/{chunk-ks5k3scp.js → chunk-pp46zp45.js} +16 -16
- package/dist/{chunk-k9q8e6d5.js → chunk-pqz3gay7.js} +35 -35
- package/dist/{chunk-3sf5yxwt.js → chunk-prgfcrhy.js} +7 -7
- package/dist/{chunk-az0j9pdk.js → chunk-ptxa1358.js} +4 -4
- package/dist/{chunk-qf28z8cg.js → chunk-pxne3x8j.js} +6 -6
- package/dist/{chunk-ddaq179m.js → chunk-q7ra5hq0.js} +9 -9
- package/dist/{chunk-6pjeqdj7.js → chunk-qa5gps5n.js} +6 -6
- package/dist/{chunk-jm0gjczx.js → chunk-qgq7k5n1.js} +3 -3
- package/dist/{chunk-9sey5nm0.js → chunk-qhr0bxds.js} +7 -7
- package/dist/{chunk-475pz7gm.js → chunk-qqj27ps5.js} +3 -3
- package/dist/{chunk-khcxv34w.js → chunk-qre271gq.js} +35 -35
- package/dist/{chunk-z018wk7e.js → chunk-qy6y2jh6.js} +2 -2
- package/dist/{chunk-83e0mt3e.js → chunk-qzmncxe1.js} +35 -35
- package/dist/{chunk-z7tmw1wy.js → chunk-r0h1fmx6.js} +48 -48
- package/dist/{chunk-k8f096rr.js → chunk-r3hnpmf2.js} +3 -3
- package/dist/{chunk-xptjm5tn.js → chunk-rb523kgm.js} +35 -35
- package/dist/{chunk-38v6jg58.js → chunk-re33t7ae.js} +6 -6
- package/dist/{chunk-xsem8235.js → chunk-rekj2av4.js} +3 -3
- package/dist/{chunk-g4wterv3.js → chunk-rfbycs7b.js} +8 -8
- package/dist/{chunk-pa2enkfb.js → chunk-rg9g7n81.js} +42 -42
- package/dist/{chunk-v88ep37v.js → chunk-rhqkpy2b.js} +39 -39
- package/dist/{chunk-1qnfymy2.js → chunk-rqwwtvv5.js} +35 -35
- package/dist/{chunk-z0kbvj67.js → chunk-s4ac4pp7.js} +36 -36
- package/dist/{chunk-dzxf88wp.js → chunk-s4sx5dc5.js} +37 -37
- package/dist/{chunk-4tjnzqpp.js → chunk-s5z2mj7c.js} +3 -3
- package/dist/{chunk-p8qppx7v.js → chunk-s8xmcaw5.js} +3 -3
- package/dist/{chunk-e3d4xr41.js → chunk-sb1dx4yy.js} +2 -2
- package/dist/{chunk-y1jfkd6q.js → chunk-sg1bpfms.js} +36 -36
- package/dist/{chunk-n6mhkhae.js → chunk-sp1rargj.js} +3 -3
- package/dist/{chunk-h526021t.js → chunk-srqavw76.js} +5 -5
- package/dist/{chunk-dxmjb0d1.js → chunk-sswwr1v8.js} +95 -95
- package/dist/{chunk-kbftt7ry.js → chunk-t0qse0mt.js} +35 -35
- package/dist/{chunk-gwek024t.js → chunk-t2a7a4z1.js} +37 -37
- package/dist/{chunk-cxvtxhjf.js → chunk-t2kp8sdc.js} +2 -2
- package/dist/{chunk-8wh7yet2.js → chunk-t2v0ebmx.js} +3 -3
- package/dist/{chunk-ebtaxjae.js → chunk-t55pghx5.js} +21 -15
- package/dist/{chunk-1z5w85hc.js → chunk-t7n4j11w.js} +35 -35
- package/dist/{chunk-45ynv6r6.js → chunk-tbq02fft.js} +2 -2
- package/dist/{chunk-0nwyc4wr.js → chunk-tesmhjvk.js} +3 -3
- package/dist/{chunk-9zs8nawy.js → chunk-tezzj9bb.js} +9 -9
- package/dist/{chunk-9qj9t1g4.js → chunk-tq15k5ay.js} +2 -2
- package/dist/{chunk-az5h0awz.js → chunk-tsm2gvad.js} +6 -6
- package/dist/{chunk-mtsvtam9.js → chunk-txnhypg4.js} +36 -36
- package/dist/{chunk-y23jxkcq.js → chunk-v5pdtb2b.js} +38 -38
- package/dist/{chunk-zd2zmk29.js → chunk-v8h3am9m.js} +4 -4
- package/dist/{chunk-fb3k2m2f.js → chunk-v9c0rpa4.js} +5 -521
- package/dist/{chunk-fapk78a0.js → chunk-vepbgbhk.js} +5 -5
- package/dist/{chunk-tsnztpmz.js → chunk-vh2bq1kq.js} +6 -6
- package/dist/{chunk-d8bfyshy.js → chunk-vjdg504j.js} +7 -7
- package/dist/{chunk-jf1z0emd.js → chunk-vyry6wjr.js} +5 -5
- package/dist/{chunk-8dehkx39.js → chunk-w4e43b9x.js} +3 -3
- package/dist/{chunk-4r70rsxj.js → chunk-w99mdc33.js} +36 -36
- package/dist/{chunk-d71xf0c6.js → chunk-w9dg1k61.js} +5 -5
- package/dist/{chunk-ap27c1aw.js → chunk-wh5tc9r0.js} +35 -35
- package/dist/{chunk-hanz1zyb.js → chunk-whnv6e1q.js} +2 -2
- package/dist/{chunk-r8bfv04s.js → chunk-wj4hsqr1.js} +38 -38
- package/dist/{chunk-22t6whmt.js → chunk-wp0pya1g.js} +37 -37
- package/dist/{chunk-wh5qdrw0.js → chunk-wvzcb6s1.js} +2 -2
- package/dist/{chunk-wkedz0qh.js → chunk-wx81sgv6.js} +2 -2
- package/dist/{chunk-1pf2k8r2.js → chunk-wxpmz8ng.js} +8 -8
- package/dist/{chunk-aernevsv.js → chunk-wz2q3pmg.js} +14 -4
- package/dist/{chunk-61p1fy8g.js → chunk-x1ge840e.js} +369 -48
- package/dist/{chunk-2hzy71d3.js → chunk-x5r53g6r.js} +35 -35
- package/dist/{chunk-a3s8wkkm.js → chunk-x78tw87y.js} +41 -41
- package/dist/{chunk-5e4sk6wr.js → chunk-x7hqhzet.js} +2 -2
- package/dist/{chunk-hvh7m0c2.js → chunk-x8g49rpq.js} +2 -2
- package/dist/{chunk-hpzhysmp.js → chunk-xajtn6jn.js} +37 -37
- package/dist/{chunk-6zkxtny0.js → chunk-xamca8ds.js} +3 -3
- package/dist/{chunk-04rgh34x.js → chunk-xcxzmq1e.js} +9 -9
- package/dist/{chunk-ksnkcjzg.js → chunk-xjmanbrm.js} +37 -37
- package/dist/{chunk-nvadgk6c.js → chunk-xkdszxwb.js} +21 -21
- package/dist/{chunk-z1dwx148.js → chunk-y01apqxs.js} +2 -2
- package/dist/{chunk-awznk2n0.js → chunk-y16r571d.js} +35 -35
- package/dist/{chunk-5hhgez0d.js → chunk-y3h553se.js} +2 -2
- package/dist/{chunk-6phpxa60.js → chunk-y754et1n.js} +2 -2
- package/dist/{chunk-j74ctwq9.js → chunk-yat2gecz.js} +2 -2
- package/dist/{chunk-m1wp25mf.js → chunk-yh6gejzw.js} +3 -3
- package/dist/{chunk-z3jg336g.js → chunk-yhmwwakf.js} +14 -14
- package/dist/{chunk-xa8k9mjs.js → chunk-yn41ejk4.js} +5 -5
- package/dist/{chunk-gh082jke.js → chunk-ypr3kzdn.js} +36 -36
- package/dist/{chunk-2dn4yh40.js → chunk-yrc25q6d.js} +2 -2
- package/dist/{chunk-2njtrn67.js → chunk-yvvzd26e.js} +5 -5
- package/dist/{chunk-eqye1zm8.js → chunk-yw9cb2g1.js} +40 -40
- package/dist/{chunk-dykkxn1f.js → chunk-yxpqycx5.js} +44 -44
- package/dist/{chunk-n191j2dd.js → chunk-yy7b3b4y.js} +3 -3
- package/dist/{chunk-gmasa1zr.js → chunk-z08t19e5.js} +2 -2
- package/dist/{chunk-k1y8sta6.js → chunk-z7wmymhj.js} +4 -5
- package/dist/{chunk-fht9he6j.js → chunk-zcgknb7z.js} +36 -36
- package/dist/{chunk-vsycm63m.js → chunk-zk2geh0a.js} +35 -35
- package/dist/{chunk-9annxcn1.js → chunk-zk84db7h.js} +18 -18
- package/dist/{chunk-7c8adbrw.js → chunk-zkf9chex.js} +36 -36
- package/dist/{chunk-pcx407qw.js → chunk-zkqykb4r.js} +38 -38
- package/dist/{chunk-6qbbdcx1.js → chunk-zqbw60sv.js} +2 -2
- package/dist/{chunk-asb7bf4r.js → chunk-zsdme624.js} +6 -6
- package/dist/{chunk-q1aw35vn.js → chunk-zsecvy91.js} +3 -3
- package/dist/{chunk-7hhh1err.js → chunk-ztetpy4q.js} +2 -2
- package/dist/cli.js +31 -31
- package/dist/services/rawDump/batchWorker.js +3 -3
- package/package.json +2 -1
- package/dist/chunk-v57at5qe.js +0 -1079
|
@@ -0,0 +1,2118 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
getProjectDir,
|
|
4
|
+
init_sessionStoragePortable
|
|
5
|
+
} from "./chunk-jakx4th4.js";
|
|
6
|
+
import {
|
|
7
|
+
init_log,
|
|
8
|
+
logError
|
|
9
|
+
} from "./chunk-vtcqe66h.js";
|
|
10
|
+
import {
|
|
11
|
+
init_slowOperations,
|
|
12
|
+
jsonParse,
|
|
13
|
+
jsonStringify
|
|
14
|
+
} from "./chunk-dea6k409.js";
|
|
15
|
+
import {
|
|
16
|
+
__require
|
|
17
|
+
} from "./chunk-qp2qdcda.js";
|
|
18
|
+
|
|
19
|
+
// src/server/sessionHandle.ts
|
|
20
|
+
init_slowOperations();
|
|
21
|
+
init_log();
|
|
22
|
+
import { spawn } from "child_process";
|
|
23
|
+
import { createInterface } from "readline";
|
|
24
|
+
import { readdir, readFile } from "fs/promises";
|
|
25
|
+
import { existsSync } from "fs";
|
|
26
|
+
import { join } from "path";
|
|
27
|
+
|
|
28
|
+
// src/server/childSpawn.ts
|
|
29
|
+
import { basename } from "path";
|
|
30
|
+
var INIT_TIMEOUT_MS = (() => {
|
|
31
|
+
const raw = Number(process.env.CSC_SERVE_INIT_TIMEOUT_MS);
|
|
32
|
+
return Number.isFinite(raw) && raw > 0 ? raw : 120000;
|
|
33
|
+
})();
|
|
34
|
+
function getScriptArgsForChild() {
|
|
35
|
+
const argv1 = process.argv[1];
|
|
36
|
+
if (!argv1)
|
|
37
|
+
return [];
|
|
38
|
+
const execBase = basename(process.execPath);
|
|
39
|
+
if (!/^(bun|node)/i.test(execBase))
|
|
40
|
+
return [];
|
|
41
|
+
if (argv1.startsWith("B:/~BUN/") || argv1.startsWith("/snapshot/"))
|
|
42
|
+
return [];
|
|
43
|
+
if (argv1 === process.execPath)
|
|
44
|
+
return [];
|
|
45
|
+
if (argv1.endsWith(".ts") || argv1.endsWith(".tsx") || argv1.includes("/") || argv1.includes("\\")) {
|
|
46
|
+
return [argv1];
|
|
47
|
+
}
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
function getChildSpawnArgs() {
|
|
51
|
+
const execPath = process.execPath;
|
|
52
|
+
const scriptArgs = getScriptArgsForChild();
|
|
53
|
+
return { execPath, scriptArgs };
|
|
54
|
+
}
|
|
55
|
+
async function saveChildSpawnPrefix() {
|
|
56
|
+
if (process.env._CSC_CHILD_SPAWN_PREFIX)
|
|
57
|
+
return;
|
|
58
|
+
const { execPath, scriptArgs } = getChildSpawnArgs();
|
|
59
|
+
let defineArgs = [];
|
|
60
|
+
let featureArgs = [];
|
|
61
|
+
const isRunningSourceFile = scriptArgs.length > 0 && (scriptArgs[0].endsWith(".tsx") || scriptArgs[0].endsWith(".ts"));
|
|
62
|
+
if (isRunningSourceFile) {
|
|
63
|
+
try {
|
|
64
|
+
const definesMod = await import("./chunk-4md0mpss.js");
|
|
65
|
+
const defines = definesMod.getMacroDefines();
|
|
66
|
+
defineArgs = Object.entries(defines).flatMap(([k, v]) => ["-d", `${k}:${v}`]);
|
|
67
|
+
const features = definesMod.DEFAULT_BUILD_FEATURES;
|
|
68
|
+
featureArgs = features.flatMap((f) => ["--feature", f]);
|
|
69
|
+
} catch {}
|
|
70
|
+
const envFeatures = Object.entries(process.env).filter(([k]) => k.startsWith("FEATURE_") && k.slice(8)).map(([k]) => ["--feature", k.slice(8)]).flat();
|
|
71
|
+
featureArgs = [...featureArgs, ...envFeatures];
|
|
72
|
+
}
|
|
73
|
+
const prefix = JSON.stringify({ execPath, scriptArgs, defineArgs, featureArgs });
|
|
74
|
+
process.env._CSC_CHILD_SPAWN_PREFIX = prefix;
|
|
75
|
+
}
|
|
76
|
+
function loadChildSpawnPrefix() {
|
|
77
|
+
const raw = process.env._CSC_CHILD_SPAWN_PREFIX;
|
|
78
|
+
if (!raw)
|
|
79
|
+
return null;
|
|
80
|
+
try {
|
|
81
|
+
return JSON.parse(raw);
|
|
82
|
+
} catch {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/server/sessionControlChannel.ts
|
|
88
|
+
class ControlChannel {
|
|
89
|
+
pending = new Map;
|
|
90
|
+
register(requestId, timeoutMs = 1e4) {
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
const timeout = setTimeout(() => {
|
|
93
|
+
this.pending.delete(requestId);
|
|
94
|
+
reject(new Error(`Control response timed out for ${requestId}`));
|
|
95
|
+
}, timeoutMs);
|
|
96
|
+
this.pending.set(requestId, { resolve, reject, timeout });
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
tryResolve(msg) {
|
|
100
|
+
if (msg.type !== "control_response")
|
|
101
|
+
return false;
|
|
102
|
+
const response = msg.response;
|
|
103
|
+
const requestId = response?.request_id;
|
|
104
|
+
if (!requestId || !this.pending.has(requestId))
|
|
105
|
+
return false;
|
|
106
|
+
const entry = this.pending.get(requestId);
|
|
107
|
+
this.pending.delete(requestId);
|
|
108
|
+
clearTimeout(entry.timeout);
|
|
109
|
+
if (response?.subtype === "error") {
|
|
110
|
+
entry.reject(new Error(response.error ?? "Unknown error"));
|
|
111
|
+
} else {
|
|
112
|
+
entry.resolve(response?.response ?? {});
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
rejectAll(error) {
|
|
117
|
+
for (const [, entry] of this.pending) {
|
|
118
|
+
clearTimeout(entry.timeout);
|
|
119
|
+
entry.reject(error);
|
|
120
|
+
}
|
|
121
|
+
this.pending.clear();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/server/sessionMessageRouter.ts
|
|
126
|
+
init_slowOperations();
|
|
127
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
128
|
+
|
|
129
|
+
// src/server/streamStateTracker.ts
|
|
130
|
+
import { randomUUID } from "crypto";
|
|
131
|
+
var states = new Map;
|
|
132
|
+
var streamedSessions = new Set;
|
|
133
|
+
var completedTools = new Map;
|
|
134
|
+
function getOrCreate(sessionID) {
|
|
135
|
+
let state = states.get(sessionID);
|
|
136
|
+
if (!state) {
|
|
137
|
+
state = {
|
|
138
|
+
messageID: randomUUID(),
|
|
139
|
+
parentID: "",
|
|
140
|
+
modelID: "",
|
|
141
|
+
activeBlocks: new Map,
|
|
142
|
+
stepStartPartID: randomUUID(),
|
|
143
|
+
assistantPartEmitted: false,
|
|
144
|
+
usage: { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 },
|
|
145
|
+
stopReason: ""
|
|
146
|
+
};
|
|
147
|
+
states.set(sessionID, state);
|
|
148
|
+
}
|
|
149
|
+
return state;
|
|
150
|
+
}
|
|
151
|
+
function resetStreamState(sessionID) {
|
|
152
|
+
states.delete(sessionID);
|
|
153
|
+
}
|
|
154
|
+
function hasActiveStream(sessionID) {
|
|
155
|
+
return states.has(sessionID);
|
|
156
|
+
}
|
|
157
|
+
function consumeStreamedTurn(sessionID) {
|
|
158
|
+
if (streamedSessions.has(sessionID)) {
|
|
159
|
+
streamedSessions.delete(sessionID);
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
var pendingAgentSessions = new Map;
|
|
165
|
+
function registerAgentSession(sessionID, toolUseID, agentSessionID) {
|
|
166
|
+
let sessionMap = pendingAgentSessions.get(sessionID);
|
|
167
|
+
if (!sessionMap) {
|
|
168
|
+
sessionMap = new Map;
|
|
169
|
+
pendingAgentSessions.set(sessionID, sessionMap);
|
|
170
|
+
}
|
|
171
|
+
sessionMap.set(toolUseID, agentSessionID);
|
|
172
|
+
}
|
|
173
|
+
function getCompletedToolInfo(sessionID, toolUseID) {
|
|
174
|
+
return completedTools.get(sessionID)?.get(toolUseID);
|
|
175
|
+
}
|
|
176
|
+
function processStreamEvent(sessionID, event) {
|
|
177
|
+
const results = [];
|
|
178
|
+
const state = getOrCreate(sessionID);
|
|
179
|
+
const eventType = event.type;
|
|
180
|
+
switch (eventType) {
|
|
181
|
+
case "message_start": {
|
|
182
|
+
const msg = event.message;
|
|
183
|
+
state.messageID = randomUUID();
|
|
184
|
+
state.modelID = msg?.model ?? "";
|
|
185
|
+
const msgUsage = msg?.usage;
|
|
186
|
+
state.usage.inputTokens = msgUsage?.input_tokens ?? 0;
|
|
187
|
+
state.usage.cacheReadTokens = msgUsage?.cache_read_input_tokens ?? 0;
|
|
188
|
+
state.usage.cacheWriteTokens = msgUsage?.cache_creation_input_tokens ?? 0;
|
|
189
|
+
state.activeBlocks.clear();
|
|
190
|
+
if (!state.assistantPartEmitted) {
|
|
191
|
+
results.push({
|
|
192
|
+
type: "message.updated",
|
|
193
|
+
properties: {
|
|
194
|
+
sessionID,
|
|
195
|
+
info: {
|
|
196
|
+
id: state.messageID,
|
|
197
|
+
role: "assistant",
|
|
198
|
+
modelID: state.modelID,
|
|
199
|
+
time: { created: Date.now() }
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
state.assistantPartEmitted = true;
|
|
204
|
+
}
|
|
205
|
+
state.stepStartPartID = randomUUID();
|
|
206
|
+
results.push({
|
|
207
|
+
type: "message.part.updated",
|
|
208
|
+
properties: {
|
|
209
|
+
sessionID,
|
|
210
|
+
part: { type: "step-start", id: state.stepStartPartID, messageID: state.messageID, sessionID }
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
case "content_block_start": {
|
|
216
|
+
const evt = event;
|
|
217
|
+
const block = evt.content_block;
|
|
218
|
+
const index = evt.index;
|
|
219
|
+
if (!block)
|
|
220
|
+
break;
|
|
221
|
+
const partID = randomUUID();
|
|
222
|
+
const blockState = {
|
|
223
|
+
type: block.type,
|
|
224
|
+
partID,
|
|
225
|
+
inputJson: "",
|
|
226
|
+
startTime: Date.now(),
|
|
227
|
+
text: ""
|
|
228
|
+
};
|
|
229
|
+
state.activeBlocks.set(index, blockState);
|
|
230
|
+
if (block.type === "text") {
|
|
231
|
+
results.push({
|
|
232
|
+
type: "message.part.updated",
|
|
233
|
+
properties: {
|
|
234
|
+
sessionID,
|
|
235
|
+
part: { type: "text", id: partID, text: "", messageID: state.messageID, sessionID }
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
} else if (block.type === "thinking" || block.type === "redacted_thinking") {
|
|
239
|
+
results.push({
|
|
240
|
+
type: "message.part.updated",
|
|
241
|
+
properties: {
|
|
242
|
+
sessionID,
|
|
243
|
+
part: {
|
|
244
|
+
type: "reasoning",
|
|
245
|
+
id: partID,
|
|
246
|
+
text: "",
|
|
247
|
+
redacted: block.type === "redacted_thinking",
|
|
248
|
+
messageID: state.messageID,
|
|
249
|
+
sessionID
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
} else if (block.type === "tool_use") {
|
|
254
|
+
blockState.toolUseID = block.id;
|
|
255
|
+
blockState.toolName = block.name;
|
|
256
|
+
results.push({
|
|
257
|
+
type: "message.part.updated",
|
|
258
|
+
properties: {
|
|
259
|
+
sessionID,
|
|
260
|
+
part: {
|
|
261
|
+
type: "tool",
|
|
262
|
+
id: partID,
|
|
263
|
+
callID: block.id,
|
|
264
|
+
tool: normalizeToolName(block.name),
|
|
265
|
+
state: { status: "pending", input: {} },
|
|
266
|
+
messageID: state.messageID,
|
|
267
|
+
sessionID
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
case "content_block_delta": {
|
|
275
|
+
const evt = event;
|
|
276
|
+
const delta = evt.delta;
|
|
277
|
+
const index = evt.index;
|
|
278
|
+
const blockState = state.activeBlocks.get(index);
|
|
279
|
+
if (!blockState || !delta)
|
|
280
|
+
break;
|
|
281
|
+
if (delta.type === "text_delta") {
|
|
282
|
+
blockState.text += delta.text ?? "";
|
|
283
|
+
results.push({
|
|
284
|
+
type: "message.part.delta",
|
|
285
|
+
properties: {
|
|
286
|
+
sessionID,
|
|
287
|
+
messageID: state.messageID,
|
|
288
|
+
partID: blockState.partID,
|
|
289
|
+
field: "text",
|
|
290
|
+
delta: delta.text
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
} else if (delta.type === "thinking_delta") {
|
|
294
|
+
blockState.text += delta.thinking ?? "";
|
|
295
|
+
results.push({
|
|
296
|
+
type: "message.part.delta",
|
|
297
|
+
properties: {
|
|
298
|
+
sessionID,
|
|
299
|
+
messageID: state.messageID,
|
|
300
|
+
partID: blockState.partID,
|
|
301
|
+
field: "text",
|
|
302
|
+
delta: delta.thinking
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
} else if (delta.type === "input_json_delta") {
|
|
306
|
+
blockState.inputJson += delta.partial_json ?? "";
|
|
307
|
+
results.push({
|
|
308
|
+
type: "message.part.delta",
|
|
309
|
+
properties: {
|
|
310
|
+
sessionID,
|
|
311
|
+
messageID: state.messageID,
|
|
312
|
+
partID: blockState.partID,
|
|
313
|
+
field: "input",
|
|
314
|
+
delta: delta.partial_json
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
case "content_block_stop": {
|
|
321
|
+
const index = event.index;
|
|
322
|
+
const blockState = state.activeBlocks.get(index);
|
|
323
|
+
if (!blockState)
|
|
324
|
+
break;
|
|
325
|
+
const now = Date.now();
|
|
326
|
+
if (blockState.type === "tool_use") {
|
|
327
|
+
let parsedInput = {};
|
|
328
|
+
try {
|
|
329
|
+
parsedInput = JSON.parse(blockState.inputJson || "{}");
|
|
330
|
+
} catch {
|
|
331
|
+
parsedInput = {};
|
|
332
|
+
}
|
|
333
|
+
parsedInput = normalizeToolInput(parsedInput);
|
|
334
|
+
const title = parsedInput.description ?? blockState.toolName ?? "";
|
|
335
|
+
const toolState = {
|
|
336
|
+
status: "running",
|
|
337
|
+
input: parsedInput,
|
|
338
|
+
title,
|
|
339
|
+
time: { start: blockState.startTime }
|
|
340
|
+
};
|
|
341
|
+
results.push({
|
|
342
|
+
type: "message.part.updated",
|
|
343
|
+
properties: {
|
|
344
|
+
sessionID,
|
|
345
|
+
part: {
|
|
346
|
+
type: "tool",
|
|
347
|
+
id: blockState.partID,
|
|
348
|
+
callID: blockState.toolUseID,
|
|
349
|
+
tool: normalizeToolName(blockState.toolName ?? ""),
|
|
350
|
+
state: toolState,
|
|
351
|
+
messageID: state.messageID,
|
|
352
|
+
sessionID
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
if (blockState.toolUseID) {
|
|
357
|
+
let sessionTools = completedTools.get(sessionID);
|
|
358
|
+
if (!sessionTools) {
|
|
359
|
+
sessionTools = new Map;
|
|
360
|
+
completedTools.set(sessionID, sessionTools);
|
|
361
|
+
}
|
|
362
|
+
sessionTools.set(blockState.toolUseID, {
|
|
363
|
+
toolName: blockState.toolName ?? "",
|
|
364
|
+
partID: blockState.partID,
|
|
365
|
+
messageID: state.messageID,
|
|
366
|
+
startTime: blockState.startTime,
|
|
367
|
+
input: parsedInput,
|
|
368
|
+
title
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
} else if (blockState.type === "text" || blockState.type === "thinking" || blockState.type === "redacted_thinking") {
|
|
372
|
+
const partType = blockState.type === "text" ? "text" : "reasoning";
|
|
373
|
+
results.push({
|
|
374
|
+
type: "message.part.updated",
|
|
375
|
+
properties: {
|
|
376
|
+
sessionID,
|
|
377
|
+
part: {
|
|
378
|
+
type: partType,
|
|
379
|
+
id: blockState.partID,
|
|
380
|
+
text: blockState.text.trimEnd(),
|
|
381
|
+
messageID: state.messageID,
|
|
382
|
+
sessionID,
|
|
383
|
+
time: { start: blockState.startTime, end: now },
|
|
384
|
+
...blockState.type === "redacted_thinking" ? { redacted: true } : {}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
state.activeBlocks.delete(index);
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
case "message_delta": {
|
|
393
|
+
const evt = event;
|
|
394
|
+
if (evt.delta?.stop_reason) {
|
|
395
|
+
state.stopReason = evt.delta.stop_reason;
|
|
396
|
+
}
|
|
397
|
+
if (evt.usage?.output_tokens) {
|
|
398
|
+
state.usage.outputTokens = evt.usage.output_tokens;
|
|
399
|
+
}
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
case "message_stop": {
|
|
403
|
+
results.push({
|
|
404
|
+
type: "message.part.updated",
|
|
405
|
+
properties: {
|
|
406
|
+
sessionID,
|
|
407
|
+
part: {
|
|
408
|
+
type: "step-finish",
|
|
409
|
+
id: randomUUID(),
|
|
410
|
+
reason: state.stopReason || "stop",
|
|
411
|
+
cost: 0,
|
|
412
|
+
tokens: {
|
|
413
|
+
input: state.usage.inputTokens,
|
|
414
|
+
output: state.usage.outputTokens,
|
|
415
|
+
reasoning: 0,
|
|
416
|
+
cache: {
|
|
417
|
+
read: state.usage.cacheReadTokens,
|
|
418
|
+
write: state.usage.cacheWriteTokens
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
messageID: state.messageID,
|
|
422
|
+
sessionID
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
results.push({
|
|
427
|
+
type: "message.updated",
|
|
428
|
+
properties: {
|
|
429
|
+
sessionID,
|
|
430
|
+
info: {
|
|
431
|
+
id: state.messageID,
|
|
432
|
+
role: "assistant",
|
|
433
|
+
modelID: state.modelID,
|
|
434
|
+
time: { completed: Date.now() }
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
resetStreamState(sessionID);
|
|
439
|
+
streamedSessions.add(sessionID);
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return results;
|
|
444
|
+
}
|
|
445
|
+
function normalizeToolInput(input) {
|
|
446
|
+
const renames = {
|
|
447
|
+
file_path: "filePath",
|
|
448
|
+
old_string: "oldString",
|
|
449
|
+
new_string: "newString",
|
|
450
|
+
replace_all: "replaceAll"
|
|
451
|
+
};
|
|
452
|
+
for (const [oldKey, newKey] of Object.entries(renames)) {
|
|
453
|
+
if (oldKey in input) {
|
|
454
|
+
input[newKey] = input[oldKey];
|
|
455
|
+
delete input[oldKey];
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return input;
|
|
459
|
+
}
|
|
460
|
+
function normalizeToolName(name) {
|
|
461
|
+
const map = {
|
|
462
|
+
Read: "read",
|
|
463
|
+
Edit: "edit",
|
|
464
|
+
Write: "edit",
|
|
465
|
+
Glob: "glob",
|
|
466
|
+
Grep: "grep",
|
|
467
|
+
LS: "list",
|
|
468
|
+
Bash: "bash",
|
|
469
|
+
PowerShell: "bash",
|
|
470
|
+
Agent: "task",
|
|
471
|
+
Task: "task",
|
|
472
|
+
WebFetch: "webfetch",
|
|
473
|
+
WebSearch: "websearch",
|
|
474
|
+
TodoRead: "todoread",
|
|
475
|
+
TodoWrite: "todowrite"
|
|
476
|
+
};
|
|
477
|
+
return map[name] ?? name.toLowerCase();
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// src/server/sessionMessageRouter.ts
|
|
481
|
+
var API_ERROR_PREFIX_RE = /^API Error:\s*/;
|
|
482
|
+
var COSTRICT_API_ERROR_PREFIX_RE = /^CoStrict API Error:\s*/;
|
|
483
|
+
var subagentToolState = new Map;
|
|
484
|
+
function isApiErrorContent(content) {
|
|
485
|
+
if (typeof content === "string") {
|
|
486
|
+
return API_ERROR_PREFIX_RE.test(content) || COSTRICT_API_ERROR_PREFIX_RE.test(content);
|
|
487
|
+
}
|
|
488
|
+
if (!Array.isArray(content))
|
|
489
|
+
return false;
|
|
490
|
+
for (const block of content) {
|
|
491
|
+
if (!block || typeof block !== "object")
|
|
492
|
+
continue;
|
|
493
|
+
const b = block;
|
|
494
|
+
if (b.type === "text" && typeof b.text === "string") {
|
|
495
|
+
const text = b.text;
|
|
496
|
+
if (API_ERROR_PREFIX_RE.test(text) || COSTRICT_API_ERROR_PREFIX_RE.test(text))
|
|
497
|
+
return true;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return false;
|
|
501
|
+
}
|
|
502
|
+
function buildErrorFromContent(content) {
|
|
503
|
+
let raw = "";
|
|
504
|
+
if (typeof content === "string") {
|
|
505
|
+
raw = content.replace(API_ERROR_PREFIX_RE, "").replace(COSTRICT_API_ERROR_PREFIX_RE, "");
|
|
506
|
+
} else if (Array.isArray(content)) {
|
|
507
|
+
for (const block of content) {
|
|
508
|
+
if (!block || typeof block !== "object")
|
|
509
|
+
continue;
|
|
510
|
+
const b = block;
|
|
511
|
+
if (b.type === "text" && typeof b.text === "string") {
|
|
512
|
+
raw = b.text.replace(API_ERROR_PREFIX_RE, "").replace(COSTRICT_API_ERROR_PREFIX_RE, "");
|
|
513
|
+
break;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
const statusMatch = raw.match(/^(\d{3})\s+/);
|
|
518
|
+
const statusCode = statusMatch ? parseInt(statusMatch[1], 10) : undefined;
|
|
519
|
+
const isRetryable = statusCode === 429 || statusCode === 503 || statusCode === 529;
|
|
520
|
+
let message = raw;
|
|
521
|
+
try {
|
|
522
|
+
const jsonStart = raw.indexOf("{");
|
|
523
|
+
if (jsonStart !== -1) {
|
|
524
|
+
const parsed = JSON.parse(raw.slice(jsonStart));
|
|
525
|
+
if (parsed?.error?.message) {
|
|
526
|
+
message = parsed.error.message;
|
|
527
|
+
} else if (typeof parsed?.message === "string") {
|
|
528
|
+
message = parsed.message;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
} catch {}
|
|
532
|
+
return { name: "APIError", data: { message, statusCode, isRetryable } };
|
|
533
|
+
}
|
|
534
|
+
function extractToolResultContent(content) {
|
|
535
|
+
if (typeof content === "string")
|
|
536
|
+
return content;
|
|
537
|
+
if (!Array.isArray(content))
|
|
538
|
+
return "";
|
|
539
|
+
const parts = [];
|
|
540
|
+
for (const block of content) {
|
|
541
|
+
if (!block || typeof block !== "object")
|
|
542
|
+
continue;
|
|
543
|
+
const b = block;
|
|
544
|
+
if (b.type === "text" && typeof b.text === "string") {
|
|
545
|
+
parts.push(b.text);
|
|
546
|
+
} else if (b.type === "image") {
|
|
547
|
+
const src = b.source;
|
|
548
|
+
if (typeof src?.data === "string") {
|
|
549
|
+
parts.push(`[image: ${src.type}]`);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
return parts.join(`
|
|
554
|
+
`);
|
|
555
|
+
}
|
|
556
|
+
function getActiveSubagentId(ctx) {
|
|
557
|
+
const subs = ctx.getActiveSubagents();
|
|
558
|
+
if (subs.size === 0)
|
|
559
|
+
return;
|
|
560
|
+
return subs.keys().next().value;
|
|
561
|
+
}
|
|
562
|
+
function getSubagentProgress(agentId) {
|
|
563
|
+
const state = subagentToolState.get(agentId);
|
|
564
|
+
if (!state)
|
|
565
|
+
return;
|
|
566
|
+
return { progressLines: state.progressLines, mainToolUseID: state.mainToolUseID };
|
|
567
|
+
}
|
|
568
|
+
function routeMessage(msg, ctx) {
|
|
569
|
+
if (ctx.getStatus() === "starting" && msg.type === "control_response") {
|
|
570
|
+
const response = msg.response;
|
|
571
|
+
if (response?.subtype === "success" && response?.request_id === ctx.getInitRequestId()) {
|
|
572
|
+
handleInitResponse(response, ctx);
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
if (msg.type === "control_response") {
|
|
577
|
+
if (ctx.getControlChannel().tryResolve(msg))
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
ctx.emitMessage(msg);
|
|
581
|
+
switch (msg.type) {
|
|
582
|
+
case "assistant": {
|
|
583
|
+
handleAssistantMessage(msg, ctx);
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
586
|
+
case "user": {
|
|
587
|
+
handleUserMessage(msg, ctx);
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
590
|
+
case "result": {
|
|
591
|
+
handleResultMessage(msg, ctx);
|
|
592
|
+
break;
|
|
593
|
+
}
|
|
594
|
+
case "control_request": {
|
|
595
|
+
handleControlRequest(msg, ctx);
|
|
596
|
+
break;
|
|
597
|
+
}
|
|
598
|
+
case "control_cancel_request": {
|
|
599
|
+
handleCancelRequest(msg, ctx);
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
602
|
+
case "stream_event": {
|
|
603
|
+
handleStreamEvent(msg, ctx);
|
|
604
|
+
break;
|
|
605
|
+
}
|
|
606
|
+
case "system": {
|
|
607
|
+
handleSystemMessage(msg, ctx);
|
|
608
|
+
break;
|
|
609
|
+
}
|
|
610
|
+
case "attachment": {
|
|
611
|
+
handleAttachment(msg, ctx);
|
|
612
|
+
break;
|
|
613
|
+
}
|
|
614
|
+
case "progress": {
|
|
615
|
+
handleProgress(msg, ctx);
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
618
|
+
case "tombstone": {
|
|
619
|
+
handleTombstone(msg, ctx);
|
|
620
|
+
break;
|
|
621
|
+
}
|
|
622
|
+
default: {
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
function handleInitResponse(response, ctx) {
|
|
628
|
+
const initData = response.response ?? {};
|
|
629
|
+
ctx.setInitData(initData);
|
|
630
|
+
if (Array.isArray(initData.models) && initData.models.length > 0 && !ctx.getModel()) {
|
|
631
|
+
const first = initData.models[0];
|
|
632
|
+
ctx.setModel(first?.value ?? first?.name);
|
|
633
|
+
}
|
|
634
|
+
if (initData.account?.apiProvider) {
|
|
635
|
+
ctx.setProviderId(initData.account.apiProvider);
|
|
636
|
+
}
|
|
637
|
+
ctx.setStatus("running");
|
|
638
|
+
ctx.setLastActiveAt(Date.now());
|
|
639
|
+
ctx.resolveInit(initData);
|
|
640
|
+
ctx.emitOpencodeEvent("session.updated", {
|
|
641
|
+
sessionID: ctx.sessionId,
|
|
642
|
+
status: "running",
|
|
643
|
+
model: ctx.getModel(),
|
|
644
|
+
providerID: ctx.getProviderId()
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
function handleAssistantMessage(msg, ctx) {
|
|
648
|
+
ctx.setLastActiveAt(Date.now());
|
|
649
|
+
ctx.setStatus("running");
|
|
650
|
+
if (msg.uuid && typeof msg.uuid === "string") {
|
|
651
|
+
ctx.setLastMessageUuid(msg.uuid);
|
|
652
|
+
}
|
|
653
|
+
const rawContent = msg.message?.content ?? msg.content;
|
|
654
|
+
const isApiError = isApiErrorContent(rawContent);
|
|
655
|
+
const agentId = msg.agent_id || getActiveSubagentId(ctx);
|
|
656
|
+
const emitSessionID = agentId && ctx.getActiveSubagents().has(agentId) ? agentId : ctx.sessionId;
|
|
657
|
+
const wasStreamed = hasActiveStream(emitSessionID) || consumeStreamedTurn(emitSessionID);
|
|
658
|
+
if (msg.uuid) {
|
|
659
|
+
ctx.pushBufferMessage({
|
|
660
|
+
uuid: msg.uuid,
|
|
661
|
+
type: "assistant",
|
|
662
|
+
role: "assistant",
|
|
663
|
+
content: isApiError ? [] : msg.message ?? msg.content ?? "",
|
|
664
|
+
timestamp: msg.timestamp ? new Date(msg.timestamp).getTime() : Date.now(),
|
|
665
|
+
parent_uuid: msg.parentUuid ?? null,
|
|
666
|
+
...isApiError ? { error: buildErrorFromContent(rawContent) } : {}
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
if (wasStreamed) {
|
|
670
|
+
if (Array.isArray(rawContent)) {
|
|
671
|
+
for (const block of rawContent) {
|
|
672
|
+
const b = block;
|
|
673
|
+
if (b.type !== "tool_result")
|
|
674
|
+
continue;
|
|
675
|
+
const toolUseID = b.tool_use_id;
|
|
676
|
+
if (!toolUseID)
|
|
677
|
+
continue;
|
|
678
|
+
const toolInfo = getCompletedToolInfo(emitSessionID, toolUseID);
|
|
679
|
+
const output = extractToolResultContent(b.content);
|
|
680
|
+
const isError = b.is_error === true;
|
|
681
|
+
ctx.emitOpencodeEvent("message.part.updated", {
|
|
682
|
+
sessionID: emitSessionID,
|
|
683
|
+
part: {
|
|
684
|
+
type: "tool",
|
|
685
|
+
id: toolInfo?.partID ?? randomUUID2(),
|
|
686
|
+
callID: toolUseID,
|
|
687
|
+
tool: toolInfo?.toolName ? normalizeToolName2(toolInfo.toolName) : "",
|
|
688
|
+
messageID: ctx.getLastMessageUuid() ?? "",
|
|
689
|
+
sessionID: emitSessionID,
|
|
690
|
+
state: {
|
|
691
|
+
status: isError ? "error" : "completed",
|
|
692
|
+
input: toolInfo?.input ?? {},
|
|
693
|
+
title: toolInfo?.title ?? toolInfo?.toolName ?? "",
|
|
694
|
+
...isError ? { error: output } : { output },
|
|
695
|
+
time: { start: toolInfo?.startTime ?? Date.now(), end: Date.now() }
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
let enriched = msg;
|
|
704
|
+
if (!msg.model && ctx.getModel()) {
|
|
705
|
+
enriched = { ...enriched, model: ctx.getModel() };
|
|
706
|
+
}
|
|
707
|
+
if (!msg.provider_id && ctx.getProviderId()) {
|
|
708
|
+
enriched = { ...enriched, provider_id: ctx.getProviderId() };
|
|
709
|
+
}
|
|
710
|
+
const assistantMsgID = msg.uuid ?? randomUUID2();
|
|
711
|
+
ctx.emitOpencodeEvent("message.updated", {
|
|
712
|
+
sessionID: emitSessionID,
|
|
713
|
+
info: {
|
|
714
|
+
id: assistantMsgID,
|
|
715
|
+
role: "assistant",
|
|
716
|
+
modelID: enriched.model,
|
|
717
|
+
providerID: enriched.provider_id,
|
|
718
|
+
cost: 0,
|
|
719
|
+
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
|
720
|
+
time: {
|
|
721
|
+
created: msg.timestamp ? new Date(msg.timestamp).getTime() : Date.now()
|
|
722
|
+
},
|
|
723
|
+
parentID: msg.parentUuid ?? null,
|
|
724
|
+
...isApiError ? { error: buildErrorFromContent(rawContent) } : {}
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
if (Array.isArray(rawContent)) {
|
|
728
|
+
for (const block of rawContent) {
|
|
729
|
+
const part = buildPartFromContentBlock(block, assistantMsgID, emitSessionID);
|
|
730
|
+
if (part) {
|
|
731
|
+
if (isApiError && part.type === "text")
|
|
732
|
+
continue;
|
|
733
|
+
ctx.emitOpencodeEvent("message.part.updated", {
|
|
734
|
+
sessionID: emitSessionID,
|
|
735
|
+
part
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
function handleUserMessage(msg, ctx) {
|
|
742
|
+
if (msg.isReplay)
|
|
743
|
+
return;
|
|
744
|
+
const agentId = msg.agent_id || getActiveSubagentId(ctx);
|
|
745
|
+
const emitSessionID = agentId && ctx.getActiveSubagents().has(agentId) ? agentId : ctx.sessionId;
|
|
746
|
+
let rawContent = msg.message ?? msg.content;
|
|
747
|
+
if (rawContent && typeof rawContent === "object" && !Array.isArray(rawContent) && "content" in rawContent) {
|
|
748
|
+
rawContent = rawContent.content;
|
|
749
|
+
}
|
|
750
|
+
if (Array.isArray(rawContent)) {
|
|
751
|
+
for (const block of rawContent) {
|
|
752
|
+
const b = block;
|
|
753
|
+
if (b.type !== "tool_result")
|
|
754
|
+
continue;
|
|
755
|
+
const toolUseID = b.tool_use_id;
|
|
756
|
+
if (!toolUseID)
|
|
757
|
+
continue;
|
|
758
|
+
const output = extractToolResultContent(b.content);
|
|
759
|
+
const isError = b.is_error === true;
|
|
760
|
+
const toolInfo = getCompletedToolInfo(emitSessionID, toolUseID);
|
|
761
|
+
ctx.emitOpencodeEvent("message.part.updated", {
|
|
762
|
+
sessionID: emitSessionID,
|
|
763
|
+
part: {
|
|
764
|
+
type: "tool",
|
|
765
|
+
id: toolInfo?.partID ?? randomUUID2(),
|
|
766
|
+
callID: toolUseID,
|
|
767
|
+
tool: toolInfo?.toolName ? normalizeToolName2(toolInfo.toolName) : "",
|
|
768
|
+
messageID: toolInfo?.messageID,
|
|
769
|
+
sessionID: emitSessionID,
|
|
770
|
+
state: {
|
|
771
|
+
status: isError ? "error" : "completed",
|
|
772
|
+
input: toolInfo?.input ?? {},
|
|
773
|
+
title: toolInfo?.title ?? toolInfo?.toolName ?? "",
|
|
774
|
+
...isError ? { error: output } : { output },
|
|
775
|
+
time: { start: toolInfo?.startTime, end: Date.now() }
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
const content = typeof msg.content === "string" ? msg.content : "";
|
|
782
|
+
if (content.includes("<local-command-stdout>"))
|
|
783
|
+
return;
|
|
784
|
+
ctx.emitOpencodeEvent("message.updated", {
|
|
785
|
+
sessionID: emitSessionID,
|
|
786
|
+
info: {
|
|
787
|
+
id: msg.uuid ?? randomUUID2(),
|
|
788
|
+
role: "user",
|
|
789
|
+
time: { created: Date.now() },
|
|
790
|
+
parentID: null
|
|
791
|
+
}
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
function handleResultMessage(msg, ctx) {
|
|
795
|
+
ctx.setLastActiveAt(Date.now());
|
|
796
|
+
ctx.setStatus("running");
|
|
797
|
+
const cost = msg.cost_usd;
|
|
798
|
+
const usage = msg.usage;
|
|
799
|
+
if (cost)
|
|
800
|
+
ctx.addCost(cost);
|
|
801
|
+
if (usage?.input_tokens)
|
|
802
|
+
ctx.addInputTokens(usage.input_tokens);
|
|
803
|
+
if (usage?.output_tokens)
|
|
804
|
+
ctx.addOutputTokens(usage.output_tokens);
|
|
805
|
+
ctx.setBusyStatus({ type: "idle" });
|
|
806
|
+
ctx.emitBusyStatus();
|
|
807
|
+
ctx.emitOpencodeEvent("session.result", {
|
|
808
|
+
sessionID: ctx.sessionId,
|
|
809
|
+
subtype: msg.subtype ?? "success",
|
|
810
|
+
costUsd: msg.cost_usd,
|
|
811
|
+
usage: msg.usage,
|
|
812
|
+
stopReason: msg.stop_reason
|
|
813
|
+
});
|
|
814
|
+
const subtype = msg.subtype;
|
|
815
|
+
if (subtype && subtype !== "success") {
|
|
816
|
+
const errorData = msg.errors;
|
|
817
|
+
const errorMessage = errorData?.[0]?.message ?? msg.subtype ?? "Unknown error";
|
|
818
|
+
ctx.emitOpencodeEvent("session.error", {
|
|
819
|
+
sessionID: ctx.sessionId,
|
|
820
|
+
error: {
|
|
821
|
+
subtype,
|
|
822
|
+
level: "error",
|
|
823
|
+
message: typeof errorMessage === "string" ? errorMessage : JSON.stringify(errorMessage)
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
ctx.resolvePrompt({ done: true });
|
|
828
|
+
}
|
|
829
|
+
function handleStreamEvent(msg, ctx) {
|
|
830
|
+
ctx.setLastActiveAt(Date.now());
|
|
831
|
+
const event = msg.event;
|
|
832
|
+
if (!event)
|
|
833
|
+
return;
|
|
834
|
+
const agentId = msg.agent_id;
|
|
835
|
+
const subagentActive = agentId && ctx.getActiveSubagents().has(agentId);
|
|
836
|
+
const emitSessionID = subagentActive ? agentId : ctx.sessionId;
|
|
837
|
+
const canonicalEvents = processStreamEvent(emitSessionID, event);
|
|
838
|
+
for (const ce of canonicalEvents) {
|
|
839
|
+
ctx.emitOpencodeEvent(ce.type, ce.properties);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
function handleSystemMessage(msg, ctx) {
|
|
843
|
+
const subtype = msg.subtype;
|
|
844
|
+
switch (subtype) {
|
|
845
|
+
case "task_notification":
|
|
846
|
+
emitTaskCompleted(msg, ctx);
|
|
847
|
+
break;
|
|
848
|
+
case "task_started":
|
|
849
|
+
emitTaskStarted(msg, ctx);
|
|
850
|
+
break;
|
|
851
|
+
case "task_progress":
|
|
852
|
+
emitTaskProgress(msg, ctx);
|
|
853
|
+
break;
|
|
854
|
+
case "api_error":
|
|
855
|
+
case "api_retry":
|
|
856
|
+
emitSessionError(msg, ctx);
|
|
857
|
+
break;
|
|
858
|
+
case "compact_boundary":
|
|
859
|
+
case "microcompact_boundary":
|
|
860
|
+
emitCompactionEvent(msg, ctx);
|
|
861
|
+
break;
|
|
862
|
+
case "stop_hook_summary":
|
|
863
|
+
emitHookSummary(msg, ctx);
|
|
864
|
+
break;
|
|
865
|
+
case "turn_duration":
|
|
866
|
+
emitSessionMetrics(msg, ctx);
|
|
867
|
+
break;
|
|
868
|
+
case "cache_warning":
|
|
869
|
+
emitSessionWarning(msg, ctx);
|
|
870
|
+
break;
|
|
871
|
+
case "informational":
|
|
872
|
+
case "post_turn_summary":
|
|
873
|
+
emitSessionInfo(msg, ctx);
|
|
874
|
+
break;
|
|
875
|
+
case "session_state_changed":
|
|
876
|
+
case "status":
|
|
877
|
+
emitSessionStatus(msg, ctx);
|
|
878
|
+
break;
|
|
879
|
+
default:
|
|
880
|
+
if (subtype) {
|
|
881
|
+
emitSessionInfo(msg, ctx);
|
|
882
|
+
}
|
|
883
|
+
break;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
function handleAttachment(msg, ctx) {
|
|
887
|
+
ctx.emitOpencodeEvent("message.attachment", {
|
|
888
|
+
sessionID: ctx.sessionId,
|
|
889
|
+
attachmentType: msg.attachment?.type,
|
|
890
|
+
attachment: msg.attachment
|
|
891
|
+
});
|
|
892
|
+
}
|
|
893
|
+
function handleProgress(msg, ctx) {
|
|
894
|
+
ctx.emitOpencodeEvent("tool.progress", {
|
|
895
|
+
sessionID: ctx.sessionId,
|
|
896
|
+
toolUseID: msg.toolUseID,
|
|
897
|
+
parentToolUseID: msg.parentToolUseID,
|
|
898
|
+
data: msg.data
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
function handleTombstone(msg, ctx) {
|
|
902
|
+
const messageObj = msg.message;
|
|
903
|
+
const targetUuid = messageObj?.uuid;
|
|
904
|
+
if (targetUuid) {
|
|
905
|
+
ctx.addTombstonedUuid(targetUuid);
|
|
906
|
+
ctx.emitOpencodeEvent("message.removed", {
|
|
907
|
+
sessionID: ctx.sessionId,
|
|
908
|
+
messageID: targetUuid
|
|
909
|
+
});
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
function handleControlRequest(msg, ctx) {
|
|
913
|
+
const request = msg.request;
|
|
914
|
+
const requestId = msg.request_id;
|
|
915
|
+
if (request?.subtype === "can_use_tool") {
|
|
916
|
+
const toolName = request.tool_name ?? "Unknown";
|
|
917
|
+
const perm = {
|
|
918
|
+
requestId,
|
|
919
|
+
sessionId: ctx.sessionId,
|
|
920
|
+
toolName,
|
|
921
|
+
toolUseId: request.tool_use_id ?? "",
|
|
922
|
+
input: request.input ?? {},
|
|
923
|
+
title: `${request.tool_name}: ${JSON.stringify(request.input).slice(0, 80)}`,
|
|
924
|
+
description: `Execute ${request.tool_name}`,
|
|
925
|
+
suggestions: request.permission_suggestions ?? []
|
|
926
|
+
};
|
|
927
|
+
ctx.getPendingPermissions().set(requestId, perm);
|
|
928
|
+
ctx.emitEvent("control_request", { request_id: requestId, request });
|
|
929
|
+
if (toolName === "AskUserQuestion") {
|
|
930
|
+
const input = request.input ?? {};
|
|
931
|
+
const questions = input.questions ?? [];
|
|
932
|
+
ctx.emitOpencodeEvent("question.asked", {
|
|
933
|
+
sessionID: ctx.sessionId,
|
|
934
|
+
id: requestId,
|
|
935
|
+
questions: questions.map((q) => ({
|
|
936
|
+
question: q.question,
|
|
937
|
+
header: q.header ?? "",
|
|
938
|
+
options: (q.options ?? []).map((o) => ({
|
|
939
|
+
label: o.label,
|
|
940
|
+
description: o.description
|
|
941
|
+
})),
|
|
942
|
+
multiple: q.multiSelect ?? false,
|
|
943
|
+
custom: false
|
|
944
|
+
})),
|
|
945
|
+
tool: {
|
|
946
|
+
messageID: "",
|
|
947
|
+
callID: perm.toolUseId
|
|
948
|
+
}
|
|
949
|
+
});
|
|
950
|
+
} else {
|
|
951
|
+
ctx.emitOpencodeEvent("permission.asked", {
|
|
952
|
+
sessionID: ctx.sessionId,
|
|
953
|
+
id: requestId,
|
|
954
|
+
permission: toPermissionKey(toolName),
|
|
955
|
+
patterns: extractPatterns(perm.input),
|
|
956
|
+
metadata: { input: perm.input },
|
|
957
|
+
always: [],
|
|
958
|
+
tool: {
|
|
959
|
+
messageID: "",
|
|
960
|
+
callID: perm.toolUseId
|
|
961
|
+
}
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
} else if (request?.subtype === "elicitation") {
|
|
965
|
+
const question = {
|
|
966
|
+
requestId,
|
|
967
|
+
sessionId: ctx.sessionId,
|
|
968
|
+
mcpServerName: request.mcp_server_name ?? "",
|
|
969
|
+
message: request.message ?? "",
|
|
970
|
+
mode: request.mode ?? "form",
|
|
971
|
+
requestedSchema: request.requested_schema ?? {}
|
|
972
|
+
};
|
|
973
|
+
ctx.getPendingQuestions().set(requestId, question);
|
|
974
|
+
ctx.emitEvent("control_request", { request_id: requestId, request });
|
|
975
|
+
ctx.emitOpencodeEvent("question.asked", {
|
|
976
|
+
sessionID: ctx.sessionId,
|
|
977
|
+
id: requestId,
|
|
978
|
+
questions: [{
|
|
979
|
+
question: question.message,
|
|
980
|
+
header: question.mcpServerName || "MCP",
|
|
981
|
+
options: [],
|
|
982
|
+
multiple: false,
|
|
983
|
+
custom: true
|
|
984
|
+
}]
|
|
985
|
+
});
|
|
986
|
+
} else if (request?.subtype === "hook_callback") {
|
|
987
|
+
ctx.emitEvent("control_request", { request_id: requestId, request });
|
|
988
|
+
const callbackId = request.callback_id;
|
|
989
|
+
if (!callbackId || callbackId === "AUTO_APPROVE_CALLBACK_ID") {
|
|
990
|
+
ctx.writeStdin(jsonStringify({
|
|
991
|
+
type: "control_response",
|
|
992
|
+
response: {
|
|
993
|
+
subtype: "success",
|
|
994
|
+
request_id: requestId,
|
|
995
|
+
response: {
|
|
996
|
+
hookSpecificOutput: {
|
|
997
|
+
hookEventName: "PreToolUse",
|
|
998
|
+
permissionDecision: "allow",
|
|
999
|
+
permissionDecisionReason: "Auto-approved by serve"
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
}));
|
|
1004
|
+
} else {
|
|
1005
|
+
ctx.writeStdin(jsonStringify({
|
|
1006
|
+
type: "control_response",
|
|
1007
|
+
response: {
|
|
1008
|
+
subtype: "success",
|
|
1009
|
+
request_id: requestId,
|
|
1010
|
+
response: {
|
|
1011
|
+
hookSpecificOutput: {
|
|
1012
|
+
hookEventName: "PreToolUse",
|
|
1013
|
+
permissionDecision: "ask",
|
|
1014
|
+
permissionDecisionReason: "Forwarding to can_use_tool"
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
}));
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
function handleCancelRequest(msg, ctx) {
|
|
1023
|
+
const cancelRequestId = msg.request_id;
|
|
1024
|
+
const wasPerm = ctx.getPendingPermissions().has(cancelRequestId);
|
|
1025
|
+
const wasQuestion = ctx.getPendingQuestions().has(cancelRequestId);
|
|
1026
|
+
ctx.getPendingPermissions().delete(cancelRequestId);
|
|
1027
|
+
ctx.getPendingQuestions().delete(cancelRequestId);
|
|
1028
|
+
if (wasQuestion) {
|
|
1029
|
+
ctx.emitOpencodeEvent("question.rejected", {
|
|
1030
|
+
sessionID: ctx.sessionId,
|
|
1031
|
+
requestID: cancelRequestId
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
if (wasPerm) {
|
|
1035
|
+
ctx.emitOpencodeEvent("permission.replied", {
|
|
1036
|
+
sessionID: ctx.sessionId,
|
|
1037
|
+
requestID: cancelRequestId
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
function buildPartFromContentBlock(block, messageID, sessionID) {
|
|
1042
|
+
switch (block.type) {
|
|
1043
|
+
case "text":
|
|
1044
|
+
return { type: "text", id: randomUUID2(), text: block.text, messageID, sessionID };
|
|
1045
|
+
case "thinking":
|
|
1046
|
+
return { type: "reasoning", id: randomUUID2(), text: block.thinking, messageID, sessionID };
|
|
1047
|
+
case "redacted_thinking":
|
|
1048
|
+
return { type: "reasoning", id: randomUUID2(), text: "", redacted: true, messageID, sessionID };
|
|
1049
|
+
case "tool_use": {
|
|
1050
|
+
const toolInput = normalizeToolInput2(block.input);
|
|
1051
|
+
return {
|
|
1052
|
+
type: "tool",
|
|
1053
|
+
id: randomUUID2(),
|
|
1054
|
+
callID: block.id,
|
|
1055
|
+
tool: normalizeToolName2(block.name),
|
|
1056
|
+
state: {
|
|
1057
|
+
status: "running",
|
|
1058
|
+
input: toolInput,
|
|
1059
|
+
title: toolInput?.description ?? block.name,
|
|
1060
|
+
time: { start: Date.now() }
|
|
1061
|
+
},
|
|
1062
|
+
messageID,
|
|
1063
|
+
sessionID
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
1066
|
+
default:
|
|
1067
|
+
return null;
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
function normalizeToolName2(name) {
|
|
1071
|
+
return toPermissionKey(name);
|
|
1072
|
+
}
|
|
1073
|
+
function emitTaskStarted(msg, ctx) {
|
|
1074
|
+
const agentId = msg.agent_id ?? msg.task_id;
|
|
1075
|
+
const taskType = msg.task_type;
|
|
1076
|
+
const description = msg.description;
|
|
1077
|
+
const prompt = msg.prompt;
|
|
1078
|
+
const toolUseId = msg.tool_use_id;
|
|
1079
|
+
const assistantMessageID = randomUUID2();
|
|
1080
|
+
ctx.registerSubagent({
|
|
1081
|
+
agentId,
|
|
1082
|
+
agentType: taskType,
|
|
1083
|
+
description,
|
|
1084
|
+
prompt,
|
|
1085
|
+
toolUseId
|
|
1086
|
+
});
|
|
1087
|
+
const toolUseIdForMain = toolUseId;
|
|
1088
|
+
subagentToolState.set(agentId, {
|
|
1089
|
+
emittedToolCount: 0,
|
|
1090
|
+
assistantMessageID,
|
|
1091
|
+
toolPartIDs: new Map,
|
|
1092
|
+
mainToolUseID: toolUseIdForMain ?? "",
|
|
1093
|
+
progressLines: []
|
|
1094
|
+
});
|
|
1095
|
+
ctx.emitOpencodeEvent("task.started", {
|
|
1096
|
+
sessionID: ctx.sessionId,
|
|
1097
|
+
taskID: msg.task_id,
|
|
1098
|
+
toolUseID: toolUseId,
|
|
1099
|
+
description,
|
|
1100
|
+
taskType,
|
|
1101
|
+
workflowName: msg.workflow_name,
|
|
1102
|
+
prompt
|
|
1103
|
+
});
|
|
1104
|
+
ctx.emitOpencodeEvent("session.created", {
|
|
1105
|
+
sessionID: agentId,
|
|
1106
|
+
info: {
|
|
1107
|
+
id: agentId,
|
|
1108
|
+
parentID: ctx.sessionId,
|
|
1109
|
+
title: description || `Subagent ${agentId.slice(0, 8)}`,
|
|
1110
|
+
agent: taskType ?? "general-purpose",
|
|
1111
|
+
createdAt: Date.now(),
|
|
1112
|
+
status: "running"
|
|
1113
|
+
}
|
|
1114
|
+
});
|
|
1115
|
+
ctx.emitOpencodeEvent("message.updated", {
|
|
1116
|
+
sessionID: agentId,
|
|
1117
|
+
info: {
|
|
1118
|
+
id: assistantMessageID,
|
|
1119
|
+
role: "assistant",
|
|
1120
|
+
modelID: "subagent",
|
|
1121
|
+
time: { created: Date.now() },
|
|
1122
|
+
parentID: null
|
|
1123
|
+
}
|
|
1124
|
+
});
|
|
1125
|
+
ctx.emitOpencodeEvent("session.status", {
|
|
1126
|
+
sessionID: agentId,
|
|
1127
|
+
status: { type: "busy" }
|
|
1128
|
+
});
|
|
1129
|
+
if (toolUseId) {
|
|
1130
|
+
registerAgentSession(ctx.sessionId, toolUseId, agentId);
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
function emitTaskProgress(msg, ctx) {
|
|
1134
|
+
const agentId = msg.agent_id ?? msg.task_id;
|
|
1135
|
+
const usage = msg.usage;
|
|
1136
|
+
const toolUses = usage?.tool_uses ?? 0;
|
|
1137
|
+
const lastToolName = msg.last_tool_name ?? "Tool";
|
|
1138
|
+
const description = msg.description;
|
|
1139
|
+
ctx.emitOpencodeEvent("task.progress", {
|
|
1140
|
+
sessionID: ctx.sessionId,
|
|
1141
|
+
taskID: msg.task_id,
|
|
1142
|
+
description,
|
|
1143
|
+
usage,
|
|
1144
|
+
lastToolName,
|
|
1145
|
+
summary: msg.summary,
|
|
1146
|
+
workflowProgress: msg.workflow_progress
|
|
1147
|
+
});
|
|
1148
|
+
const toolState = subagentToolState.get(agentId);
|
|
1149
|
+
if (!toolState)
|
|
1150
|
+
return;
|
|
1151
|
+
if (description) {
|
|
1152
|
+
const lines = toolState.progressLines;
|
|
1153
|
+
lines.push(description);
|
|
1154
|
+
if (lines.length > 3)
|
|
1155
|
+
lines.splice(0, lines.length - 3);
|
|
1156
|
+
toolState.progressLines = lines;
|
|
1157
|
+
if (toolState.mainToolUseID) {
|
|
1158
|
+
const mainToolInfo = getCompletedToolInfo(ctx.sessionId, toolState.mainToolUseID);
|
|
1159
|
+
ctx.emitOpencodeEvent("message.part.updated", {
|
|
1160
|
+
sessionID: ctx.sessionId,
|
|
1161
|
+
part: {
|
|
1162
|
+
type: "tool",
|
|
1163
|
+
id: randomUUID2(),
|
|
1164
|
+
callID: toolState.mainToolUseID,
|
|
1165
|
+
tool: mainToolInfo?.toolName ? normalizeToolName2(mainToolInfo.toolName) : "task",
|
|
1166
|
+
state: {
|
|
1167
|
+
status: "running",
|
|
1168
|
+
input: mainToolInfo?.input ?? {},
|
|
1169
|
+
title: mainToolInfo?.title ?? "",
|
|
1170
|
+
time: { start: mainToolInfo?.startTime ?? Date.now() },
|
|
1171
|
+
progress: toolState.progressLines
|
|
1172
|
+
},
|
|
1173
|
+
messageID: mainToolInfo?.messageID ?? "",
|
|
1174
|
+
sessionID: ctx.sessionId
|
|
1175
|
+
}
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
while (toolState.emittedToolCount < toolUses) {
|
|
1180
|
+
toolState.emittedToolCount++;
|
|
1181
|
+
const toolIndex = toolState.emittedToolCount;
|
|
1182
|
+
const isLast = toolIndex === toolUses;
|
|
1183
|
+
const toolName = toolIndex === toolUses ? lastToolName : "Tool";
|
|
1184
|
+
let partID = toolState.toolPartIDs.get(toolIndex);
|
|
1185
|
+
if (!partID) {
|
|
1186
|
+
partID = randomUUID2();
|
|
1187
|
+
toolState.toolPartIDs.set(toolIndex, partID);
|
|
1188
|
+
}
|
|
1189
|
+
ctx.emitOpencodeEvent("message.part.updated", {
|
|
1190
|
+
sessionID: agentId,
|
|
1191
|
+
part: {
|
|
1192
|
+
type: "tool",
|
|
1193
|
+
id: partID,
|
|
1194
|
+
callID: `subagent-tool-${toolIndex}`,
|
|
1195
|
+
tool: normalizeToolName2(toolName),
|
|
1196
|
+
state: {
|
|
1197
|
+
status: "completed",
|
|
1198
|
+
output: isLast && description ? description.replace(/^Running\s*/i, "") : "",
|
|
1199
|
+
title: `${toolName} #${toolIndex}`,
|
|
1200
|
+
time: { start: Date.now() - (usage?.duration_ms ?? 0), end: Date.now() }
|
|
1201
|
+
},
|
|
1202
|
+
messageID: toolState.assistantMessageID,
|
|
1203
|
+
sessionID: agentId
|
|
1204
|
+
}
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
function emitTaskCompleted(msg, ctx) {
|
|
1209
|
+
const agentId = msg.agent_id ?? msg.task_id;
|
|
1210
|
+
const status = msg.status;
|
|
1211
|
+
const summary = msg.summary;
|
|
1212
|
+
const toolUseId = msg.tool_use_id;
|
|
1213
|
+
const toolState = subagentToolState.get(agentId);
|
|
1214
|
+
ctx.emitOpencodeEvent("task.completed", {
|
|
1215
|
+
sessionID: ctx.sessionId,
|
|
1216
|
+
taskID: msg.task_id,
|
|
1217
|
+
toolUseID: toolUseId,
|
|
1218
|
+
status,
|
|
1219
|
+
summary,
|
|
1220
|
+
outputFile: msg.output_file,
|
|
1221
|
+
usage: msg.usage
|
|
1222
|
+
});
|
|
1223
|
+
if (toolUseId) {
|
|
1224
|
+
const agentToolInfo = getCompletedToolInfo(ctx.sessionId, toolUseId);
|
|
1225
|
+
ctx.emitOpencodeEvent("message.part.updated", {
|
|
1226
|
+
sessionID: ctx.sessionId,
|
|
1227
|
+
part: {
|
|
1228
|
+
type: "tool",
|
|
1229
|
+
id: agentToolInfo?.partID ?? randomUUID2(),
|
|
1230
|
+
callID: toolUseId,
|
|
1231
|
+
tool: agentToolInfo?.toolName ? normalizeToolName2(agentToolInfo.toolName) : undefined,
|
|
1232
|
+
messageID: agentToolInfo?.messageID,
|
|
1233
|
+
sessionID: ctx.sessionId,
|
|
1234
|
+
state: {
|
|
1235
|
+
status: status === "failed" ? "error" : "completed",
|
|
1236
|
+
input: agentToolInfo?.input ?? {},
|
|
1237
|
+
...status === "failed" ? { error: summary || "Task failed" } : { output: summary || "" },
|
|
1238
|
+
title: summary || "",
|
|
1239
|
+
time: { start: agentToolInfo?.startTime, end: Date.now() }
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1244
|
+
if (toolState) {
|
|
1245
|
+
ctx.emitOpencodeEvent("message.updated", {
|
|
1246
|
+
sessionID: agentId,
|
|
1247
|
+
info: {
|
|
1248
|
+
id: toolState.assistantMessageID,
|
|
1249
|
+
role: "assistant",
|
|
1250
|
+
modelID: "subagent",
|
|
1251
|
+
time: { completed: Date.now() }
|
|
1252
|
+
}
|
|
1253
|
+
});
|
|
1254
|
+
subagentToolState.delete(agentId);
|
|
1255
|
+
}
|
|
1256
|
+
const subagent = ctx.getActiveSubagents().get(agentId);
|
|
1257
|
+
if (subagent || agentId) {
|
|
1258
|
+
ctx.emitOpencodeEvent("session.updated", {
|
|
1259
|
+
sessionID: agentId,
|
|
1260
|
+
info: {
|
|
1261
|
+
id: agentId,
|
|
1262
|
+
status,
|
|
1263
|
+
summary,
|
|
1264
|
+
completedAt: Date.now()
|
|
1265
|
+
}
|
|
1266
|
+
});
|
|
1267
|
+
ctx.emitOpencodeEvent("session.status", {
|
|
1268
|
+
sessionID: agentId,
|
|
1269
|
+
status: { type: "idle" }
|
|
1270
|
+
});
|
|
1271
|
+
ctx.emitOpencodeEvent("session.idle", {
|
|
1272
|
+
sessionID: agentId
|
|
1273
|
+
});
|
|
1274
|
+
ctx.unregisterSubagent(agentId);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
function emitSessionError(msg, ctx) {
|
|
1278
|
+
ctx.emitOpencodeEvent("session.error", {
|
|
1279
|
+
sessionID: ctx.sessionId,
|
|
1280
|
+
error: {
|
|
1281
|
+
subtype: msg.subtype,
|
|
1282
|
+
level: msg.level ?? "error",
|
|
1283
|
+
message: msg.content ?? msg.error?.message,
|
|
1284
|
+
retryInMs: msg.retry_in_ms ?? msg.retryInMs,
|
|
1285
|
+
retryAttempt: msg.retry_attempt ?? msg.retryAttempt,
|
|
1286
|
+
maxRetries: msg.max_retries ?? msg.maxRetries
|
|
1287
|
+
}
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
function emitCompactionEvent(msg, ctx) {
|
|
1291
|
+
ctx.emitOpencodeEvent("message.part.updated", {
|
|
1292
|
+
sessionID: ctx.sessionId,
|
|
1293
|
+
part: {
|
|
1294
|
+
type: "compaction",
|
|
1295
|
+
id: msg.uuid ?? randomUUID2(),
|
|
1296
|
+
auto: msg.subtype === "microcompact_boundary" || msg.compact_metadata?.trigger === "auto"
|
|
1297
|
+
}
|
|
1298
|
+
});
|
|
1299
|
+
}
|
|
1300
|
+
function emitHookSummary(msg, ctx) {
|
|
1301
|
+
ctx.emitOpencodeEvent("session.hook_summary", {
|
|
1302
|
+
sessionID: ctx.sessionId,
|
|
1303
|
+
hookLabel: msg.hook_label ?? msg.hookLabel,
|
|
1304
|
+
hookCount: msg.hook_count ?? msg.hookCount,
|
|
1305
|
+
hookErrors: msg.hook_errors ?? msg.hookErrors,
|
|
1306
|
+
preventedContinuation: msg.prevented_continuation ?? msg.preventedContinuation,
|
|
1307
|
+
totalDurationMs: msg.total_duration_ms ?? msg.totalDurationMs
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
function emitSessionMetrics(msg, ctx) {
|
|
1311
|
+
ctx.emitOpencodeEvent("session.metrics", {
|
|
1312
|
+
sessionID: ctx.sessionId,
|
|
1313
|
+
turnDuration: msg.duration ?? msg.turn_duration
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1316
|
+
function emitSessionWarning(msg, ctx) {
|
|
1317
|
+
ctx.emitOpencodeEvent("session.warning", {
|
|
1318
|
+
sessionID: ctx.sessionId,
|
|
1319
|
+
message: msg.content
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
function emitSessionInfo(msg, ctx) {
|
|
1323
|
+
ctx.emitOpencodeEvent("session.info", {
|
|
1324
|
+
sessionID: ctx.sessionId,
|
|
1325
|
+
subtype: msg.subtype,
|
|
1326
|
+
content: msg.content
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
function emitSessionStatus(msg, ctx) {
|
|
1330
|
+
ctx.emitOpencodeEvent("session.status", {
|
|
1331
|
+
sessionID: ctx.sessionId,
|
|
1332
|
+
status: msg.status
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1335
|
+
function toPermissionKey(toolName) {
|
|
1336
|
+
const map = {
|
|
1337
|
+
Read: "read",
|
|
1338
|
+
Edit: "edit",
|
|
1339
|
+
Write: "edit",
|
|
1340
|
+
Glob: "glob",
|
|
1341
|
+
Grep: "grep",
|
|
1342
|
+
LS: "list",
|
|
1343
|
+
Bash: "bash",
|
|
1344
|
+
PowerShell: "bash",
|
|
1345
|
+
Agent: "task",
|
|
1346
|
+
WebFetch: "webfetch",
|
|
1347
|
+
WebSearch: "websearch",
|
|
1348
|
+
TodoRead: "todoread",
|
|
1349
|
+
TodoWrite: "todowrite"
|
|
1350
|
+
};
|
|
1351
|
+
return map[toolName] ?? toolName.toLowerCase();
|
|
1352
|
+
}
|
|
1353
|
+
function extractPatterns(input) {
|
|
1354
|
+
const patterns = [];
|
|
1355
|
+
for (const key of ["file_path", "path", "pattern", "glob"]) {
|
|
1356
|
+
const v = typeof input[key] === "string" ? input[key] : "";
|
|
1357
|
+
if (v)
|
|
1358
|
+
patterns.push(v);
|
|
1359
|
+
}
|
|
1360
|
+
const cmd = typeof input.command === "string" ? input.command : "";
|
|
1361
|
+
if (cmd)
|
|
1362
|
+
patterns.push(cmd);
|
|
1363
|
+
return patterns;
|
|
1364
|
+
}
|
|
1365
|
+
function normalizeToolInput2(input) {
|
|
1366
|
+
const renames = {
|
|
1367
|
+
file_path: "filePath",
|
|
1368
|
+
old_string: "oldString",
|
|
1369
|
+
new_string: "newString",
|
|
1370
|
+
replace_all: "replaceAll"
|
|
1371
|
+
};
|
|
1372
|
+
for (const [oldKey, newKey] of Object.entries(renames)) {
|
|
1373
|
+
if (oldKey in input) {
|
|
1374
|
+
input[newKey] = input[oldKey];
|
|
1375
|
+
delete input[oldKey];
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
return input;
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
// src/server/sessionHandle.ts
|
|
1382
|
+
init_sessionStoragePortable();
|
|
1383
|
+
class SessionHandle {
|
|
1384
|
+
opts;
|
|
1385
|
+
sessionId;
|
|
1386
|
+
cwd;
|
|
1387
|
+
_spawnCwd;
|
|
1388
|
+
child = null;
|
|
1389
|
+
_status = "starting";
|
|
1390
|
+
_busyStatus = { type: "idle" };
|
|
1391
|
+
_model;
|
|
1392
|
+
_agent;
|
|
1393
|
+
_providerId;
|
|
1394
|
+
_permissionMode;
|
|
1395
|
+
_title;
|
|
1396
|
+
_costUsd = 0;
|
|
1397
|
+
_inputTokens = 0;
|
|
1398
|
+
_outputTokens = 0;
|
|
1399
|
+
createdAt = Date.now();
|
|
1400
|
+
lastActiveAt = Date.now();
|
|
1401
|
+
eventBus;
|
|
1402
|
+
pendingPermissions = new Map;
|
|
1403
|
+
pendingQuestions = new Map;
|
|
1404
|
+
promptResolve = null;
|
|
1405
|
+
promptReject = null;
|
|
1406
|
+
verbose;
|
|
1407
|
+
lastStderr = [];
|
|
1408
|
+
listeners = new Set;
|
|
1409
|
+
_initData = null;
|
|
1410
|
+
initRequestId = null;
|
|
1411
|
+
initResolve = null;
|
|
1412
|
+
initReject = null;
|
|
1413
|
+
_prompting = false;
|
|
1414
|
+
_lastMessageUuid = null;
|
|
1415
|
+
_controlChannel = new ControlChannel;
|
|
1416
|
+
_titleGenerationAttempted = false;
|
|
1417
|
+
_firstPromptContent;
|
|
1418
|
+
_messageBuffer = [];
|
|
1419
|
+
_tombstonedUuids = new Set;
|
|
1420
|
+
_activeSubagents = new Map;
|
|
1421
|
+
_subagentIndex = new Map;
|
|
1422
|
+
get subagentIndex() {
|
|
1423
|
+
return this._subagentIndex;
|
|
1424
|
+
}
|
|
1425
|
+
get tombstonedUuids() {
|
|
1426
|
+
return this._tombstonedUuids;
|
|
1427
|
+
}
|
|
1428
|
+
get activeSubagents() {
|
|
1429
|
+
return this._activeSubagents;
|
|
1430
|
+
}
|
|
1431
|
+
get status() {
|
|
1432
|
+
return this._status;
|
|
1433
|
+
}
|
|
1434
|
+
get busyStatus() {
|
|
1435
|
+
return this._busyStatus;
|
|
1436
|
+
}
|
|
1437
|
+
get model() {
|
|
1438
|
+
return this._model;
|
|
1439
|
+
}
|
|
1440
|
+
get agent() {
|
|
1441
|
+
return this._agent;
|
|
1442
|
+
}
|
|
1443
|
+
get permissionMode() {
|
|
1444
|
+
return this._permissionMode;
|
|
1445
|
+
}
|
|
1446
|
+
get title() {
|
|
1447
|
+
return this._title;
|
|
1448
|
+
}
|
|
1449
|
+
get costUsd() {
|
|
1450
|
+
return this._costUsd;
|
|
1451
|
+
}
|
|
1452
|
+
get inputTokens() {
|
|
1453
|
+
return this._inputTokens;
|
|
1454
|
+
}
|
|
1455
|
+
get messageCount() {
|
|
1456
|
+
return 0;
|
|
1457
|
+
}
|
|
1458
|
+
get usage() {
|
|
1459
|
+
return {
|
|
1460
|
+
input_tokens: this._inputTokens,
|
|
1461
|
+
output_tokens: this._outputTokens
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
get initData() {
|
|
1465
|
+
return this._initData;
|
|
1466
|
+
}
|
|
1467
|
+
get prompting() {
|
|
1468
|
+
return this._prompting;
|
|
1469
|
+
}
|
|
1470
|
+
get messageBuffer() {
|
|
1471
|
+
return this._messageBuffer;
|
|
1472
|
+
}
|
|
1473
|
+
pushMessage(msg) {
|
|
1474
|
+
if (this._messageBuffer.length > 0) {
|
|
1475
|
+
const last = this._messageBuffer[this._messageBuffer.length - 1];
|
|
1476
|
+
if (last.uuid === msg.uuid)
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1479
|
+
this._messageBuffer.push(msg);
|
|
1480
|
+
}
|
|
1481
|
+
get lastMessageUuid() {
|
|
1482
|
+
return this._lastMessageUuid;
|
|
1483
|
+
}
|
|
1484
|
+
getEffectiveBusyStatus() {
|
|
1485
|
+
if (this._prompting) {
|
|
1486
|
+
return { type: "busy" };
|
|
1487
|
+
}
|
|
1488
|
+
if (this._status === "stopped") {
|
|
1489
|
+
return { type: "idle" };
|
|
1490
|
+
}
|
|
1491
|
+
return this._busyStatus;
|
|
1492
|
+
}
|
|
1493
|
+
get ready() {
|
|
1494
|
+
return this._status === "running";
|
|
1495
|
+
}
|
|
1496
|
+
get silent() {
|
|
1497
|
+
return this.opts.silent ?? false;
|
|
1498
|
+
}
|
|
1499
|
+
get spawnCwd() {
|
|
1500
|
+
return this._spawnCwd ?? this.cwd;
|
|
1501
|
+
}
|
|
1502
|
+
async waitReady(timeoutMs = INIT_TIMEOUT_MS) {
|
|
1503
|
+
if (this._status === "running")
|
|
1504
|
+
return;
|
|
1505
|
+
if (this._status === "stopped") {
|
|
1506
|
+
throw new Error(`Session ${this.sessionId} is stopped`);
|
|
1507
|
+
}
|
|
1508
|
+
return new Promise((resolve, reject) => {
|
|
1509
|
+
const timer = setTimeout(() => {
|
|
1510
|
+
reject(new Error(`Session ${this.sessionId} init timed out`));
|
|
1511
|
+
}, timeoutMs);
|
|
1512
|
+
const origResolve = this.initResolve;
|
|
1513
|
+
const origReject = this.initReject;
|
|
1514
|
+
this.initResolve = (data) => {
|
|
1515
|
+
clearTimeout(timer);
|
|
1516
|
+
origResolve?.(data);
|
|
1517
|
+
resolve();
|
|
1518
|
+
};
|
|
1519
|
+
this.initReject = (err) => {
|
|
1520
|
+
clearTimeout(timer);
|
|
1521
|
+
origReject?.(err);
|
|
1522
|
+
reject(err);
|
|
1523
|
+
};
|
|
1524
|
+
});
|
|
1525
|
+
}
|
|
1526
|
+
constructor(opts) {
|
|
1527
|
+
this.opts = opts;
|
|
1528
|
+
this.sessionId = opts.sessionId;
|
|
1529
|
+
this.cwd = opts.cwd;
|
|
1530
|
+
this.eventBus = opts.eventBus;
|
|
1531
|
+
this._model = opts.model;
|
|
1532
|
+
this._agent = opts.agent;
|
|
1533
|
+
this._permissionMode = opts.permissionMode ?? "default";
|
|
1534
|
+
this.verbose = opts.verbose ?? false;
|
|
1535
|
+
}
|
|
1536
|
+
onMessage(listener) {
|
|
1537
|
+
this.listeners.add(listener);
|
|
1538
|
+
return () => {
|
|
1539
|
+
this.listeners.delete(listener);
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1542
|
+
async buildSubagentIndex() {
|
|
1543
|
+
const projectDir = getProjectDir(this.cwd);
|
|
1544
|
+
const sessionDir = join(projectDir, this.sessionId, "subagents");
|
|
1545
|
+
if (!existsSync(sessionDir))
|
|
1546
|
+
return;
|
|
1547
|
+
try {
|
|
1548
|
+
const entries = await readdir(sessionDir);
|
|
1549
|
+
for (const entry of entries) {
|
|
1550
|
+
if (!entry.startsWith("agent-") || !entry.endsWith(".jsonl"))
|
|
1551
|
+
continue;
|
|
1552
|
+
const agentId = entry.slice("agent-".length, -".jsonl".length);
|
|
1553
|
+
const transcriptPath = join(sessionDir, entry);
|
|
1554
|
+
const metaPath = transcriptPath.replace(/\.jsonl$/, ".meta.json");
|
|
1555
|
+
let meta = {};
|
|
1556
|
+
try {
|
|
1557
|
+
const raw = await readFile(metaPath, "utf-8");
|
|
1558
|
+
meta = JSON.parse(raw);
|
|
1559
|
+
} catch {}
|
|
1560
|
+
this._subagentIndex.set(agentId, { transcriptPath, meta });
|
|
1561
|
+
}
|
|
1562
|
+
} catch {}
|
|
1563
|
+
}
|
|
1564
|
+
spawn() {
|
|
1565
|
+
const printArgs = [
|
|
1566
|
+
"--print",
|
|
1567
|
+
"--input-format",
|
|
1568
|
+
"stream-json",
|
|
1569
|
+
"--output-format",
|
|
1570
|
+
"stream-json",
|
|
1571
|
+
...this.opts.resumeSessionId ? [] : ["--session-id", this.sessionId],
|
|
1572
|
+
...this.opts.model ? ["--model", this.opts.model] : [],
|
|
1573
|
+
...this._agent ? ["--agent", this._agent] : [],
|
|
1574
|
+
"--permission-mode",
|
|
1575
|
+
this._permissionMode,
|
|
1576
|
+
"--permission-prompt-tool",
|
|
1577
|
+
"stdio",
|
|
1578
|
+
...this.opts.resumeSessionId ? ["--resume", this.opts.resumeSessionId] : [],
|
|
1579
|
+
...this.opts.resumeSessionAt ? ["--resume-session-at", this.opts.resumeSessionAt] : [],
|
|
1580
|
+
"--verbose"
|
|
1581
|
+
];
|
|
1582
|
+
const env = {
|
|
1583
|
+
...process.env,
|
|
1584
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1",
|
|
1585
|
+
CSC_SERVE_MODE: "1"
|
|
1586
|
+
};
|
|
1587
|
+
if (this.opts.systemPrompt) {
|
|
1588
|
+
env.CLAUDE_CODE_SYSTEM_PROMPT = this.opts.systemPrompt;
|
|
1589
|
+
}
|
|
1590
|
+
const saved = loadChildSpawnPrefix();
|
|
1591
|
+
const defineArgs = saved?.defineArgs ?? [];
|
|
1592
|
+
const featureArgs = saved?.featureArgs ?? [];
|
|
1593
|
+
const spawnArgs = [
|
|
1594
|
+
...defineArgs,
|
|
1595
|
+
...featureArgs,
|
|
1596
|
+
...this.opts.scriptArgs,
|
|
1597
|
+
...printArgs.filter((x) => x != null)
|
|
1598
|
+
];
|
|
1599
|
+
this._spawnCwd = this.opts.cwd;
|
|
1600
|
+
this.child = spawn(this.opts.execPath, spawnArgs, {
|
|
1601
|
+
cwd: this.opts.cwd,
|
|
1602
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
1603
|
+
env,
|
|
1604
|
+
windowsHide: true
|
|
1605
|
+
});
|
|
1606
|
+
this.setupStdout();
|
|
1607
|
+
this.setupStderr();
|
|
1608
|
+
this.child.on("close", (code, signal) => {
|
|
1609
|
+
if (this._status !== "stopped") {
|
|
1610
|
+
this._status = "stopped";
|
|
1611
|
+
this._busyStatus = { type: "idle" };
|
|
1612
|
+
this.emitBusyStatus();
|
|
1613
|
+
this.emitOpencodeEvent("session.deleted", {
|
|
1614
|
+
sessionID: this.sessionId,
|
|
1615
|
+
status: "stopped",
|
|
1616
|
+
exit_code: code,
|
|
1617
|
+
signal: signal ?? null
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1620
|
+
if (this.initReject) {
|
|
1621
|
+
const reject = this.initReject;
|
|
1622
|
+
this.initResolve = null;
|
|
1623
|
+
this.initReject = null;
|
|
1624
|
+
process.stderr.write(`[serve:${this.sessionId}] exit_code=${code} cwd=${this.cwd} stderr:
|
|
1625
|
+
${this.lastStderr.slice(-5).join(`
|
|
1626
|
+
`)}
|
|
1627
|
+
`);
|
|
1628
|
+
reject(new Error(`Process exited with code ${code}`));
|
|
1629
|
+
}
|
|
1630
|
+
if (this.promptReject) {
|
|
1631
|
+
this.promptReject(new Error(`Process exited with code ${code}`));
|
|
1632
|
+
}
|
|
1633
|
+
});
|
|
1634
|
+
this.child.on("error", (err) => {
|
|
1635
|
+
logError(err);
|
|
1636
|
+
this._status = "stopped";
|
|
1637
|
+
this._busyStatus = { type: "idle" };
|
|
1638
|
+
this.emitBusyStatus();
|
|
1639
|
+
if (this.initReject) {
|
|
1640
|
+
const reject = this.initReject;
|
|
1641
|
+
this.initResolve = null;
|
|
1642
|
+
this.initReject = null;
|
|
1643
|
+
reject(err);
|
|
1644
|
+
}
|
|
1645
|
+
if (this.promptReject) {
|
|
1646
|
+
this.promptReject(err);
|
|
1647
|
+
}
|
|
1648
|
+
});
|
|
1649
|
+
this.initRequestId = crypto.randomUUID();
|
|
1650
|
+
this.sendInitialize();
|
|
1651
|
+
const timeout = setTimeout(() => {
|
|
1652
|
+
if (this.initReject) {
|
|
1653
|
+
const reject = this.initReject;
|
|
1654
|
+
this.initResolve = null;
|
|
1655
|
+
this.initReject = null;
|
|
1656
|
+
this._status = "stopped";
|
|
1657
|
+
this.emitOpencodeEvent("session.deleted", {
|
|
1658
|
+
sessionID: this.sessionId,
|
|
1659
|
+
status: "stopped",
|
|
1660
|
+
reason: "init_timeout"
|
|
1661
|
+
});
|
|
1662
|
+
reject(new Error(`Session ${this.sessionId} init timed out`));
|
|
1663
|
+
}
|
|
1664
|
+
}, INIT_TIMEOUT_MS);
|
|
1665
|
+
this.initResolve = (data) => {
|
|
1666
|
+
clearTimeout(timeout);
|
|
1667
|
+
this.initReject = null;
|
|
1668
|
+
};
|
|
1669
|
+
this.initReject = (_err) => {
|
|
1670
|
+
clearTimeout(timeout);
|
|
1671
|
+
this.initResolve = null;
|
|
1672
|
+
};
|
|
1673
|
+
}
|
|
1674
|
+
async start() {
|
|
1675
|
+
if (!this.child) {
|
|
1676
|
+
this.spawn();
|
|
1677
|
+
}
|
|
1678
|
+
if (this._status === "running")
|
|
1679
|
+
return;
|
|
1680
|
+
return new Promise((resolve, reject) => {
|
|
1681
|
+
const origResolve = this.initResolve;
|
|
1682
|
+
const origReject = this.initReject;
|
|
1683
|
+
this.initResolve = (data) => {
|
|
1684
|
+
origResolve?.(data);
|
|
1685
|
+
resolve();
|
|
1686
|
+
};
|
|
1687
|
+
this.initReject = (err) => {
|
|
1688
|
+
origReject?.(err);
|
|
1689
|
+
reject(err);
|
|
1690
|
+
};
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
sendInitialize() {
|
|
1694
|
+
const request = {
|
|
1695
|
+
subtype: "initialize"
|
|
1696
|
+
};
|
|
1697
|
+
if (this.opts.hooks) {
|
|
1698
|
+
request.hooks = this.opts.hooks;
|
|
1699
|
+
}
|
|
1700
|
+
const msg = jsonStringify({
|
|
1701
|
+
type: "control_request",
|
|
1702
|
+
request_id: this.initRequestId,
|
|
1703
|
+
request
|
|
1704
|
+
});
|
|
1705
|
+
this.writeStdin(msg);
|
|
1706
|
+
}
|
|
1707
|
+
setupStdout() {
|
|
1708
|
+
if (!this.child?.stdout)
|
|
1709
|
+
return;
|
|
1710
|
+
const rl = createInterface({ input: this.child.stdout });
|
|
1711
|
+
rl.on("line", (line) => {
|
|
1712
|
+
if (!line.trim())
|
|
1713
|
+
return;
|
|
1714
|
+
let msg;
|
|
1715
|
+
try {
|
|
1716
|
+
msg = jsonParse(line);
|
|
1717
|
+
} catch {
|
|
1718
|
+
return;
|
|
1719
|
+
}
|
|
1720
|
+
routeMessage(msg, this.createRouterCtx());
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1723
|
+
setupStderr() {
|
|
1724
|
+
if (!this.child?.stderr)
|
|
1725
|
+
return;
|
|
1726
|
+
const rl = createInterface({ input: this.child.stderr });
|
|
1727
|
+
rl.on("line", (line) => {
|
|
1728
|
+
if (this.verbose) {
|
|
1729
|
+
process.stderr.write(`[serve:${this.sessionId}] ${line}
|
|
1730
|
+
`);
|
|
1731
|
+
}
|
|
1732
|
+
if (this.lastStderr.length >= 20) {
|
|
1733
|
+
this.lastStderr.shift();
|
|
1734
|
+
}
|
|
1735
|
+
this.lastStderr.push(line);
|
|
1736
|
+
});
|
|
1737
|
+
}
|
|
1738
|
+
emitEvent(event, data) {
|
|
1739
|
+
if (this.opts.silent)
|
|
1740
|
+
return;
|
|
1741
|
+
this.eventBus.publishSessionEvent(this.sessionId, event, data);
|
|
1742
|
+
}
|
|
1743
|
+
emitOpencodeEvent(event, properties) {
|
|
1744
|
+
if (this.opts.silent)
|
|
1745
|
+
return;
|
|
1746
|
+
this.eventBus.publish(event, {
|
|
1747
|
+
_native_opencode: true,
|
|
1748
|
+
session_id: properties.sessionID,
|
|
1749
|
+
...properties
|
|
1750
|
+
});
|
|
1751
|
+
}
|
|
1752
|
+
emitBusyStatus() {
|
|
1753
|
+
if (this.opts.silent)
|
|
1754
|
+
return;
|
|
1755
|
+
this.eventBus.publish("session.status", {
|
|
1756
|
+
sessionID: this.sessionId,
|
|
1757
|
+
status: this._busyStatus
|
|
1758
|
+
});
|
|
1759
|
+
}
|
|
1760
|
+
emitMessage(msg) {
|
|
1761
|
+
for (const listener of this.listeners) {
|
|
1762
|
+
try {
|
|
1763
|
+
listener(msg);
|
|
1764
|
+
} catch {}
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
writeStdin(data) {
|
|
1768
|
+
if (this.child?.stdin && !this.child.stdin.destroyed) {
|
|
1769
|
+
const flushed = this.child.stdin.write(data + `
|
|
1770
|
+
`);
|
|
1771
|
+
if (!flushed) {
|
|
1772
|
+
this.child.stdin.once("drain", () => {});
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
createRouterCtx() {
|
|
1777
|
+
return {
|
|
1778
|
+
sessionId: this.sessionId,
|
|
1779
|
+
silent: this.opts.silent ?? false,
|
|
1780
|
+
getStatus: () => this._status,
|
|
1781
|
+
getBusyStatus: () => this._busyStatus,
|
|
1782
|
+
getModel: () => this._model,
|
|
1783
|
+
getProviderId: () => this._providerId,
|
|
1784
|
+
getInitRequestId: () => this.initRequestId,
|
|
1785
|
+
getLastMessageUuid: () => this._lastMessageUuid,
|
|
1786
|
+
setStatus: (s) => {
|
|
1787
|
+
this._status = s;
|
|
1788
|
+
},
|
|
1789
|
+
setBusyStatus: (s) => {
|
|
1790
|
+
this._busyStatus = s;
|
|
1791
|
+
},
|
|
1792
|
+
setModel: (m) => {
|
|
1793
|
+
this._model = m;
|
|
1794
|
+
},
|
|
1795
|
+
setProviderId: (id) => {
|
|
1796
|
+
this._providerId = id;
|
|
1797
|
+
},
|
|
1798
|
+
setInitData: (d) => {
|
|
1799
|
+
this._initData = d;
|
|
1800
|
+
},
|
|
1801
|
+
setLastMessageUuid: (u) => {
|
|
1802
|
+
this._lastMessageUuid = u;
|
|
1803
|
+
},
|
|
1804
|
+
setLastActiveAt: (t) => {
|
|
1805
|
+
this.lastActiveAt = t;
|
|
1806
|
+
},
|
|
1807
|
+
addCost: (c) => {
|
|
1808
|
+
this._costUsd += c;
|
|
1809
|
+
},
|
|
1810
|
+
addInputTokens: (t) => {
|
|
1811
|
+
this._inputTokens += t;
|
|
1812
|
+
},
|
|
1813
|
+
addOutputTokens: (t) => {
|
|
1814
|
+
this._outputTokens += t;
|
|
1815
|
+
},
|
|
1816
|
+
getControlChannel: () => this._controlChannel,
|
|
1817
|
+
getPendingPermissions: () => this.pendingPermissions,
|
|
1818
|
+
getPendingQuestions: () => this.pendingQuestions,
|
|
1819
|
+
resolveInit: (data) => {
|
|
1820
|
+
const resolve = this.initResolve;
|
|
1821
|
+
this.initResolve = null;
|
|
1822
|
+
this.initReject = null;
|
|
1823
|
+
resolve?.(data);
|
|
1824
|
+
this.opts.onInit?.(data);
|
|
1825
|
+
},
|
|
1826
|
+
resolvePrompt: (value) => {
|
|
1827
|
+
this._busyStatus = { type: "idle" };
|
|
1828
|
+
this.emitBusyStatus();
|
|
1829
|
+
if (this.promptResolve) {
|
|
1830
|
+
this.promptResolve(value);
|
|
1831
|
+
this.promptResolve = null;
|
|
1832
|
+
this.promptReject = null;
|
|
1833
|
+
}
|
|
1834
|
+
if (this._firstPromptContent && !this._titleGenerationAttempted) {
|
|
1835
|
+
this._titleGenerationAttempted = true;
|
|
1836
|
+
const content = this._firstPromptContent;
|
|
1837
|
+
this.sendControlRequest({
|
|
1838
|
+
subtype: "generate_session_title",
|
|
1839
|
+
description: content,
|
|
1840
|
+
persist: true
|
|
1841
|
+
}, 30000).then((res) => {
|
|
1842
|
+
const title = res.title || content.slice(0, 100);
|
|
1843
|
+
this.setTitle(title);
|
|
1844
|
+
}).catch(() => {
|
|
1845
|
+
this.setTitle(content.slice(0, 100));
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1848
|
+
},
|
|
1849
|
+
emitEvent: (event, data) => this.emitEvent(event, data),
|
|
1850
|
+
emitOpencodeEvent: (event, props) => this.emitOpencodeEvent(event, props),
|
|
1851
|
+
emitBusyStatus: () => this.emitBusyStatus(),
|
|
1852
|
+
emitMessage: (msg) => this.emitMessage(msg),
|
|
1853
|
+
writeStdin: (data) => this.writeStdin(data),
|
|
1854
|
+
pushBufferMessage: (msg) => this.pushMessage(msg),
|
|
1855
|
+
addTombstonedUuid: (uuid) => this._tombstonedUuids.add(uuid),
|
|
1856
|
+
getActiveSubagents: () => this._activeSubagents,
|
|
1857
|
+
registerSubagent: (info) => this._activeSubagents.set(info.agentId, info),
|
|
1858
|
+
unregisterSubagent: (agentId) => this._activeSubagents.delete(agentId)
|
|
1859
|
+
};
|
|
1860
|
+
}
|
|
1861
|
+
setTitle(title) {
|
|
1862
|
+
this._title = title;
|
|
1863
|
+
this.emitOpencodeEvent("session.updated", {
|
|
1864
|
+
sessionID: this.sessionId,
|
|
1865
|
+
status: this._status,
|
|
1866
|
+
model: this._model,
|
|
1867
|
+
title: this._title,
|
|
1868
|
+
providerID: this._providerId
|
|
1869
|
+
});
|
|
1870
|
+
}
|
|
1871
|
+
async sendControlRequest(request, timeoutMs = 1e4) {
|
|
1872
|
+
const requestId = crypto.randomUUID();
|
|
1873
|
+
this.writeStdin(jsonStringify({
|
|
1874
|
+
type: "control_request",
|
|
1875
|
+
request_id: requestId,
|
|
1876
|
+
request
|
|
1877
|
+
}));
|
|
1878
|
+
return this._controlChannel.register(requestId, timeoutMs);
|
|
1879
|
+
}
|
|
1880
|
+
async setModel(model) {
|
|
1881
|
+
this._model = model;
|
|
1882
|
+
await this.sendControlRequest({ subtype: "set_model", model });
|
|
1883
|
+
}
|
|
1884
|
+
async setAgent(agent) {
|
|
1885
|
+
this._agent = agent;
|
|
1886
|
+
await this.sendControlRequest({ subtype: "set_agent", agent });
|
|
1887
|
+
}
|
|
1888
|
+
async setPermissionMode(mode) {
|
|
1889
|
+
this._permissionMode = mode;
|
|
1890
|
+
await this.sendControlRequest({ subtype: "set_permission_mode", mode });
|
|
1891
|
+
}
|
|
1892
|
+
async getMcpStatus() {
|
|
1893
|
+
const response = await this.sendControlRequest({ subtype: "mcp_status" });
|
|
1894
|
+
return response.mcpServers ?? [];
|
|
1895
|
+
}
|
|
1896
|
+
async prompt(content, opts) {
|
|
1897
|
+
if (this._status === "stopped") {
|
|
1898
|
+
throw new Error(`Session ${this.sessionId} is stopped`);
|
|
1899
|
+
}
|
|
1900
|
+
if (this._prompting) {
|
|
1901
|
+
throw new Error(`Session ${this.sessionId} is already processing a prompt`);
|
|
1902
|
+
}
|
|
1903
|
+
this._prompting = true;
|
|
1904
|
+
const alreadyBusy = this._busyStatus?.type === "busy";
|
|
1905
|
+
if (!alreadyBusy) {
|
|
1906
|
+
this._busyStatus = { type: "busy" };
|
|
1907
|
+
this.emitBusyStatus();
|
|
1908
|
+
}
|
|
1909
|
+
this.lastActiveAt = Date.now();
|
|
1910
|
+
const uuid = opts?.messageID ?? crypto.randomUUID();
|
|
1911
|
+
const userMsg = jsonStringify({
|
|
1912
|
+
type: "user",
|
|
1913
|
+
content,
|
|
1914
|
+
uuid,
|
|
1915
|
+
session_id: this.sessionId,
|
|
1916
|
+
message: { role: "user", content },
|
|
1917
|
+
parent_tool_use_id: null
|
|
1918
|
+
});
|
|
1919
|
+
this.emitOpencodeEvent("message.updated", {
|
|
1920
|
+
sessionID: this.sessionId,
|
|
1921
|
+
info: {
|
|
1922
|
+
id: uuid,
|
|
1923
|
+
role: "user",
|
|
1924
|
+
modelID: this._model ?? "",
|
|
1925
|
+
providerID: this._providerId ?? "",
|
|
1926
|
+
time: { created: Date.now() },
|
|
1927
|
+
parentID: null
|
|
1928
|
+
}
|
|
1929
|
+
});
|
|
1930
|
+
this.pushMessage({
|
|
1931
|
+
uuid,
|
|
1932
|
+
type: "user",
|
|
1933
|
+
role: "user",
|
|
1934
|
+
content,
|
|
1935
|
+
timestamp: Date.now(),
|
|
1936
|
+
parent_uuid: null
|
|
1937
|
+
});
|
|
1938
|
+
this.writeStdin(userMsg);
|
|
1939
|
+
if (!this._title && !this._titleGenerationAttempted) {
|
|
1940
|
+
this._firstPromptContent = content;
|
|
1941
|
+
}
|
|
1942
|
+
return new Promise((resolve, reject) => {
|
|
1943
|
+
this.promptResolve = (value) => {
|
|
1944
|
+
this._prompting = false;
|
|
1945
|
+
resolve(value);
|
|
1946
|
+
};
|
|
1947
|
+
this.promptReject = (reason) => {
|
|
1948
|
+
this._prompting = false;
|
|
1949
|
+
reject(reason);
|
|
1950
|
+
};
|
|
1951
|
+
});
|
|
1952
|
+
}
|
|
1953
|
+
async abort() {
|
|
1954
|
+
if (!this.child || this.child.killed)
|
|
1955
|
+
return;
|
|
1956
|
+
const interrupt = jsonStringify({
|
|
1957
|
+
type: "control_request",
|
|
1958
|
+
request_id: crypto.randomUUID(),
|
|
1959
|
+
request: { subtype: "interrupt" }
|
|
1960
|
+
});
|
|
1961
|
+
this.writeStdin(interrupt);
|
|
1962
|
+
this._busyStatus = { type: "idle" };
|
|
1963
|
+
this.emitBusyStatus();
|
|
1964
|
+
this.emitOpencodeEvent("session.result", {
|
|
1965
|
+
sessionID: this.sessionId,
|
|
1966
|
+
subtype: "error_during_execution",
|
|
1967
|
+
is_error: true,
|
|
1968
|
+
is_interrupted: true
|
|
1969
|
+
});
|
|
1970
|
+
if (!this.promptResolve)
|
|
1971
|
+
return;
|
|
1972
|
+
await new Promise((resolve) => {
|
|
1973
|
+
const timeout = setTimeout(() => {
|
|
1974
|
+
this.kill();
|
|
1975
|
+
resolve();
|
|
1976
|
+
}, 2000);
|
|
1977
|
+
const originalResolve = this.promptResolve;
|
|
1978
|
+
this.promptResolve = (value) => {
|
|
1979
|
+
clearTimeout(timeout);
|
|
1980
|
+
originalResolve?.(value);
|
|
1981
|
+
resolve();
|
|
1982
|
+
};
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1985
|
+
replyPermission(requestId, behavior, opts) {
|
|
1986
|
+
const response = {
|
|
1987
|
+
type: "control_response",
|
|
1988
|
+
response: {
|
|
1989
|
+
subtype: "success",
|
|
1990
|
+
request_id: requestId,
|
|
1991
|
+
response: behavior === "allow" ? {
|
|
1992
|
+
behavior: "allow",
|
|
1993
|
+
updatedInput: opts?.updatedInput ?? {},
|
|
1994
|
+
...opts?.updatedPermissions ? { updatedPermissions: opts.updatedPermissions } : {},
|
|
1995
|
+
...opts?.decisionClassification ? { decisionClassification: opts.decisionClassification } : {}
|
|
1996
|
+
} : {
|
|
1997
|
+
behavior: "deny",
|
|
1998
|
+
message: opts?.message ?? "Denied",
|
|
1999
|
+
...opts?.interrupt ? { interrupt: true } : {}
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
};
|
|
2003
|
+
this.writeStdin(jsonStringify(response));
|
|
2004
|
+
const perm = this.getPendingPermission(requestId);
|
|
2005
|
+
const toolName = perm?.toolName;
|
|
2006
|
+
this.pendingPermissions.delete(requestId);
|
|
2007
|
+
this.emitEvent("permission_replied", {
|
|
2008
|
+
request_id: requestId,
|
|
2009
|
+
behavior
|
|
2010
|
+
});
|
|
2011
|
+
if (toolName === "AskUserQuestion") {
|
|
2012
|
+
const eventType = behavior === "allow" ? "question.replied" : "question.rejected";
|
|
2013
|
+
this.emitOpencodeEvent(eventType, {
|
|
2014
|
+
sessionID: this.sessionId,
|
|
2015
|
+
requestID: requestId
|
|
2016
|
+
});
|
|
2017
|
+
} else {
|
|
2018
|
+
this.emitOpencodeEvent("permission.replied", {
|
|
2019
|
+
sessionID: this.sessionId,
|
|
2020
|
+
requestID: requestId
|
|
2021
|
+
});
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
replyQuestion(requestId, action, content) {
|
|
2025
|
+
const response = {
|
|
2026
|
+
type: "control_response",
|
|
2027
|
+
response: {
|
|
2028
|
+
subtype: "success",
|
|
2029
|
+
request_id: requestId,
|
|
2030
|
+
response: action === "accept" ? { action: "accept", content } : { action: "decline" }
|
|
2031
|
+
}
|
|
2032
|
+
};
|
|
2033
|
+
this.writeStdin(jsonStringify(response));
|
|
2034
|
+
this.pendingQuestions.delete(requestId);
|
|
2035
|
+
this.emitEvent("question_replied", {
|
|
2036
|
+
request_id: requestId,
|
|
2037
|
+
action
|
|
2038
|
+
});
|
|
2039
|
+
const eventType = action === "accept" ? "question.replied" : "question.rejected";
|
|
2040
|
+
this.emitOpencodeEvent(eventType, {
|
|
2041
|
+
sessionID: this.sessionId,
|
|
2042
|
+
requestID: requestId
|
|
2043
|
+
});
|
|
2044
|
+
}
|
|
2045
|
+
kill() {
|
|
2046
|
+
if (this.child && !this.child.killed) {
|
|
2047
|
+
if (process.platform === "win32") {
|
|
2048
|
+
this.child.kill();
|
|
2049
|
+
} else {
|
|
2050
|
+
this.child.kill("SIGTERM");
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
this._status = "stopped";
|
|
2054
|
+
this._controlChannel.rejectAll(new Error("Session killed"));
|
|
2055
|
+
}
|
|
2056
|
+
forceKill() {
|
|
2057
|
+
if (this.child && !this.child.killed) {
|
|
2058
|
+
if (process.platform === "win32") {
|
|
2059
|
+
this.child.kill();
|
|
2060
|
+
} else {
|
|
2061
|
+
this.child.kill("SIGKILL");
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
this._status = "stopped";
|
|
2065
|
+
this._controlChannel.rejectAll(new Error("Session force killed"));
|
|
2066
|
+
}
|
|
2067
|
+
[Symbol.dispose]() {
|
|
2068
|
+
this.forceKill();
|
|
2069
|
+
}
|
|
2070
|
+
getPendingPermissions() {
|
|
2071
|
+
return [...this.pendingPermissions.values()];
|
|
2072
|
+
}
|
|
2073
|
+
getPendingPermission(requestId) {
|
|
2074
|
+
return this.pendingPermissions.get(requestId);
|
|
2075
|
+
}
|
|
2076
|
+
getPendingQuestions() {
|
|
2077
|
+
return [...this.pendingQuestions.values()];
|
|
2078
|
+
}
|
|
2079
|
+
getPendingQuestion(requestId) {
|
|
2080
|
+
return this.pendingQuestions.get(requestId);
|
|
2081
|
+
}
|
|
2082
|
+
handleMessage(msg) {
|
|
2083
|
+
routeMessage(msg, this.createRouterCtx());
|
|
2084
|
+
}
|
|
2085
|
+
getLastStderr() {
|
|
2086
|
+
return [...this.lastStderr];
|
|
2087
|
+
}
|
|
2088
|
+
getInfo() {
|
|
2089
|
+
return {
|
|
2090
|
+
id: this.sessionId,
|
|
2091
|
+
session_id: this.sessionId,
|
|
2092
|
+
slug: this.sessionId,
|
|
2093
|
+
projectID: "",
|
|
2094
|
+
directory: this.cwd,
|
|
2095
|
+
cwd: this.cwd,
|
|
2096
|
+
title: this._title,
|
|
2097
|
+
version: "",
|
|
2098
|
+
time: {
|
|
2099
|
+
created: this.createdAt,
|
|
2100
|
+
updated: this.lastActiveAt
|
|
2101
|
+
},
|
|
2102
|
+
status: this._status,
|
|
2103
|
+
model: this._model,
|
|
2104
|
+
permission_mode: this._permissionMode,
|
|
2105
|
+
created_at: this.createdAt,
|
|
2106
|
+
last_active_at: this.lastActiveAt,
|
|
2107
|
+
cost_usd: this._costUsd,
|
|
2108
|
+
input_tokens: this._inputTokens,
|
|
2109
|
+
output_tokens: this._outputTokens,
|
|
2110
|
+
last_message_uuid: this._lastMessageUuid
|
|
2111
|
+
};
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2115
|
+
export { getScriptArgsForChild, getChildSpawnArgs, saveChildSpawnPrefix, getSubagentProgress, SessionHandle };
|
|
2116
|
+
|
|
2117
|
+
//# debugId=39BAD054F367F45364756E2164756E21
|
|
2118
|
+
//# sourceMappingURL=chunk-ksav9jw1.js.map
|