elanous 0.2.23 → 0.2.25
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/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +1 -0
- package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +36 -0
- package/apps/pwa/out/_next/static/chunks/1146.80d15ea7c6e6ee95.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1157.f08bf2b70915e176.js +148 -0
- package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1454-37fd16f479f5554a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8532.a86e99acf9b761cb.js → 1516.83dd2c1b86b4e507.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{89849432.9eaa2f4c9c010965.js → 16e57f67.3ea19e893461e611.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1505.5826671109111e75.js → 1743.563d3168e95825ef.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +27 -0
- package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2528.3868070ef1be69f9.js +24 -0
- package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2697.76ca2ac3efef6f3b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +32 -0
- package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2846.d6a433b8663819a5.js +309 -0
- package/apps/pwa/out/_next/static/chunks/3143.257997a5f1ed79df.js +34 -0
- package/apps/pwa/out/_next/static/chunks/{5967-c0a80f8ffe5d4050.js → 3259-86f3be56e43eaf6a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3309.364573ceedbdfd5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +287 -0
- package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5578.ac963634373b28c6.js → 4084.15ecaf4240bd9e77.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8438.ee7f0df3b3f6fcb4.js → 4204.a409ab6250c0f6a8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +8 -0
- package/apps/pwa/out/_next/static/chunks/4565-67e4c620597965c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7905.b230b9d06cb4ad5d.js → 4593.10f5b9bd702d4a6c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +104 -0
- package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +149 -0
- package/apps/pwa/out/_next/static/chunks/{8569.b853a8daa8f31d12.js → 5081.a240b63fad28663a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2528.0af5c0e1fad88df6.js → 5408.377c8c543635b81f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9502-32c5dc22e8f120f5.js → 5492-e05e26a033ba80d2.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/5785-ea8d2c633b6688e3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/599-a914cc0468f56143.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +23 -0
- package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5974.360f8441eb0ac1ec.js → 6196.34d6b229079e9e28.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +77 -0
- package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +64 -0
- package/apps/pwa/out/_next/static/chunks/{ce383d63.d2ede338788ed18e.js → 65ebff95.081daeff622d238e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +2 -0
- package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{83cfc5c8.349535543c1548b6.js → 6def8a8e.c81f9ca41028eccf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2721.bc9a8f36bd85c07a.js → 7483.ba01c6c209b81bba.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +62 -0
- package/apps/pwa/out/_next/static/chunks/{6702.ebbd165d5e4a4a14.js → 7752.5cbdd0b433c54af9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8925-2abfb48af477fb7f.js → 8085-1e5fce59500a2cc2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +226 -0
- package/apps/pwa/out/_next/static/chunks/{b4e12462-5fab4a813a63dadd.js → 83a80514-b897b64df43ce108.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +93 -0
- package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{8264.00e434fbd02e9311.js → 8578.dff22d988cc2b106.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +115 -0
- package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +41 -0
- package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +74 -0
- package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +94 -0
- package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7518.49161e8f5814abdb.js → 9311.24c8f5ea793253dd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9976.8f28864317639fe6.js → 94.4cfed21c0b781a06.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/949.1e7d45ccb71580aa.js +90 -0
- package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{0e3acd34.d42b2ef87fdf4234.js → 973cbf1b.3bbcf2b41548eca7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6571-926ddf024a6ad5df.js → 9917-9e26abc5f7772735.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9938.b23e4d4dfa0114cd.js +79 -0
- package/apps/pwa/out/_next/static/chunks/{740.90b31555290236a9.js → 9974.e77b4ff4884557b3.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{4c5e95ce.83e9b16add6fcd8c.js → ab4d57c2.e90bc2cb31949045.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-9360b1285b2a346e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f08f6529d09ffae1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-f000d54d258f9ef6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-ad3bd8084048bee4.js → page-b12149c51f7d04b1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-22f674e7e4c2c9d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8888733e40cea6d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-9717ec6964b92276.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-44eaad486bc98a45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-97fa6cf3d34c7eb9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-305cd294e754906e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/{page-a648bc464c9dc754.js → page-dea4b795741126fd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-35e05d7450461a67.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-45889e7070d11126.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-16a2e893f83ae4d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-b2638013c0bf7dfd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-56888bc744e08dac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-c44f93a41167536f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-952c6ceec6d9de38.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-6d0202af568f4c63.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-1b810474507f3702.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-74366ae2693a7d95.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-4fb6fc34e20c07b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-e9502921f4f01b1f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-b6169ea2f09cf287.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-6a14333d1b1b3967.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-8c91a9a66c9ec90a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-48fb31810693c357.js → page-4e634c5b98fd4e93.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ed3070d637850548.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/{page-cb154acadb025414.js → page-b9cc8a10bc6078b4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/page-3d3fc73dd187ed52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-128458c8d86fbb5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-9c04dac0831c2bbb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-cf0c2b0183991d09.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-04de9ca6d52a3893.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-62527677bbc2fdc4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9a2e09c4a311764c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-bfeb35d69e8b24bb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-89cb33bced824e4a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-b008aff96be56654.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-814394dcbae789b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-6a87325c87f09dd2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-6445ac4cbb8dd869.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-852170303c6cd755.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-087ceeb975ef272b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-97c7361cc2a19319.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-20162174b77f96cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-8c6901833f897496.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-05a4b2c9b91034aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{53746282.1be36038d1abd949.js → e117f801.e92bf10242653497.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/e87d89b9.2e71c0ae475d28a1.js +122 -0
- package/apps/pwa/out/_next/static/chunks/{0673cc54.8e2ef1c23e49e190.js → f4dfbfc0.a69fb12f854882aa.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +1 -0
- package/apps/pwa/out/_next/static/css/72becfd42807b50d.css +1 -0
- package/apps/pwa/out/_next/static/{rfkMm4movqkqMebBrCXiR → dRS6lEhSRRBr1abbzp7fJ}/_buildManifest.js +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +23 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/catalog/models/openrouter/deepseek-v4-pro-0813.yaml +39 -0
- package/catalog/models/openrouter/deepseek-v4.1-flash.yaml +38 -0
- package/catalog/models/openrouter/glm-5.3-flash.yaml +35 -0
- package/catalog/providers/openrouter.yaml +2 -0
- package/graphs/implement-loop.yaml +31 -0
- package/graphs/ops/harness-gc.yaml +17 -0
- package/graphs/ops/recipes.yaml +3 -0
- package/graphs/overlays/README.md +1 -1
- package/graphs/overlays/stop-heal-ladder.yaml +105 -0
- package/graphs/release/release-loop.yaml +5 -5
- package/graphs/steward/recipes.yaml +4 -0
- package/graphs/steward/steward.yaml +10 -1
- package/package.json +1 -1
- package/scripts/add-api-key.sh +1 -1
- package/scripts/bench-report.ts +46 -1
- package/scripts/ci-typecheck-changed.ts +73 -14
- package/scripts/fleet/bedrock-pod-secret.ts +122 -0
- package/scripts/fleet/node-setup-linux.sh +97 -0
- package/scripts/fleet/node-setup.sh +11 -0
- package/scripts/fleet/zai-pod-secret.ts +86 -0
- package/scripts/land-global-checks.ts +3 -0
- package/scripts/measure-log-diet-2.ts +213 -0
- package/scripts/measure-tsc-affected-roots.ts +289 -0
- package/scripts/release-loop/auto-approve-node.ts +6 -0
- package/scripts/release-loop/gate-closure.ts +286 -0
- package/scripts/release-loop/gate-executor.ts +28 -0
- package/scripts/release-loop/gate-node.ts +333 -37
- package/scripts/release-loop/gate-partial.ts +34 -6
- package/scripts/release-loop/ops-upgrade-node.ts +63 -42
- package/scripts/release-loop/publish-node.ts +6 -0
- package/scripts/release-loop/resume-release.ts +46 -13
- package/scripts/release-loop/resume.ts +110 -4
- package/scripts/release-loop/unattended-release.ts +22 -7
- package/scripts/tsc-baseline-cache.ts +172 -0
- package/scripts/usage-rollup.ts +72 -6
- package/scripts/ux-sim.ts +30 -1
- package/skills/youtube-master/scripts/main.ts +4 -1
- package/skills/youtube-master/src/obsidian.ts +9 -0
- package/src/agent/run-context.ts +10 -0
- package/src/agent-mission/driver.ts +18 -3
- package/src/agent-mission/resource-ladder.ts +8 -3
- package/src/agent-mission/review-loop.ts +8 -2
- package/src/agent-substrate/acp-implementer.ts +146 -0
- package/src/agent-substrate/pr-reviewer.ts +60 -13
- package/src/agent-substrate/self-review-cli.ts +170 -15
- package/src/autopilot/mission-critique.ts +18 -5
- package/src/autopilot/mission-feasibility-negotiate.ts +11 -10
- package/src/autopilot/mission-trace.ts +12 -1
- package/src/autopilot/system-lookback-run.ts +16 -10
- package/src/bench/bench.ts +183 -0
- package/src/budget/cost-tier-advisor.ts +91 -0
- package/src/budget/fetchers/grok.ts +15 -5
- package/src/budget/llm-cost.ts +37 -5
- package/src/budget/shadow-arms.ts +77 -0
- package/src/budget/types.ts +10 -2
- package/src/budget/unified-usage.ts +256 -10
- package/src/cli/bench-cli.ts +34 -0
- package/src/cli/doctor-cli.ts +21 -0
- package/src/cli/friendly-errors.ts +113 -0
- package/src/cli/guardian-cli.ts +26 -1
- package/src/cli/image-cli.ts +101 -0
- package/src/cli/intake-cli.ts +3 -1
- package/src/cli/log-event-names.ts +4 -0
- package/src/cli/memory-cli.ts +182 -0
- package/src/cli/model-watch-cli.ts +4 -1
- package/src/cli/pr-cli.ts +62 -5
- package/src/cli/pr-land-overlap-evidence.ts +160 -12
- package/src/cli/pr-land-pod-shadow.ts +54 -0
- package/src/cli/release-cli.ts +27 -16
- package/src/cli/release-run-if-ready.ts +11 -0
- package/src/cli/resource-cli.ts +48 -0
- package/src/cli/retro-cli.ts +12 -3
- package/src/cli/rfc-status.ts +52 -2
- package/src/cli/seat-requests-cli.ts +25 -0
- package/src/cli/self-update.ts +104 -0
- package/src/cli/tasks-cli.ts +139 -10
- package/src/cli/usage-cli.ts +93 -8
- package/src/compact/verify-probe.ts +23 -3
- package/src/context-card/index.ts +50 -0
- package/src/control/control-status.ts +30 -1
- package/src/core-turn/run-goal-loop.ts +5 -4
- package/src/dashboard/ad-run-setup-bindings.ts +279 -0
- package/src/dashboard/index.ts +18 -276
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +4 -138
- package/src/dashboard/slash-runtime/shell-slash.ts +145 -0
- package/src/dashboard/stale-install-check.ts +11 -0
- package/src/debug/log-diet.ts +53 -10
- package/src/debug/log.ts +19 -1
- package/src/domains/morning-essential.ts +18 -3
- package/src/domains/release-tool.ts +43 -0
- package/src/error-report/report.ts +21 -4
- package/src/execution-loop/launch-gate.ts +158 -2
- package/src/fleet/host-doctor.ts +375 -0
- package/src/github/pr-labels.ts +1 -0
- package/src/goals/judge.ts +20 -6
- package/src/graph-runner/graph-cli.ts +42 -1
- package/src/graph-runner/runner.ts +176 -11
- package/src/graph-wizard/archetypes.ts +14 -8
- package/src/graph-wizard/generate.ts +77 -1
- package/src/grok/usage.ts +23 -2
- package/src/grok.ts +13 -7
- package/src/grounding/ref-index.ts +253 -0
- package/src/harness/dispatch-backpressure.ts +10 -2
- package/src/harness/harness-clean.ts +199 -78
- package/src/harness/harness-cli-command.ts +176 -52
- package/src/harness/harness-gc.ts +331 -0
- package/src/harness/harness-stop.ts +82 -10
- package/src/harness/harness-substrate-default.ts +142 -7
- package/src/harness/launch-registry.ts +6 -0
- package/src/harness/worktree-branch-prefix.ts +9 -0
- package/src/hq/fence.ts +187 -0
- package/src/hq/seats.ts +38 -22
- package/src/images/image-ledger.ts +179 -0
- package/src/index.ts +110 -186
- package/src/instance/child-scope.ts +32 -1
- package/src/instance/dev-project.ts +133 -0
- package/src/instance/resolve.ts +24 -0
- package/src/instance/spawn-elanous.ts +45 -0
- package/src/intake-plane/collect-github.ts +7 -2
- package/src/intake-plane/lens.ts +46 -4
- package/src/intake-plane/ref-prefetch.ts +110 -0
- package/src/intake-plane/requirement-funnel.ts +53 -1
- package/src/intelligence-map/catalog-feed.ts +119 -0
- package/src/intelligence-map/model-catalog.ts +72 -0
- package/src/intelligence-map/model-watch-intake.ts +40 -0
- package/src/intelligence-map/model-watch-mission.ts +14 -1
- package/src/llm/bedrock-eventstream.ts +215 -0
- package/src/llm/bedrock-provider.ts +114 -41
- package/src/llm/bedrock.ts +174 -28
- package/src/llm/open-weight-discipline.ts +21 -0
- package/src/llm/openrouter-byok-cost.ts +96 -0
- package/src/llm/openrouter-deepseek.ts +151 -0
- package/src/llm/openrouter-upstream-pins.config.ts +25 -0
- package/src/llm/zai-coding-plan.ts +700 -0
- package/src/llm.ts +91 -24
- package/src/loops/checker.ts +148 -9
- package/src/loops/orchestrator/resync-shadow.ts +34 -7
- package/src/maturity/feature-maturity.ts +3 -3
- package/src/model-tier/llm-tier-map.ts +9 -5
- package/src/models/prompts.ts +2 -1
- package/src/mss/logging/log-store.ts +58 -11
- package/src/nexus/api/http-server.ts +22 -0
- package/src/nexus/api/missions.ts +73 -2
- package/src/nexus/api/ops-api.ts +18 -0
- package/src/nexus/index.ts +7 -75
- package/src/nexus/tools-kind.ts +78 -0
- package/src/oauth/codex-account-rotation.ts +43 -3
- package/src/oauth/codex-account-store.ts +339 -27
- package/src/oauth/codex-quota-policy.ts +33 -4
- package/src/oauth/fallback-chain.ts +53 -15
- package/src/onboarding/first-run.ts +37 -18
- package/src/onboarding/web-first.ts +20 -2
- package/src/ops/machine-heartbeat.ts +185 -0
- package/src/ops/overview-cache.ts +175 -0
- package/src/ops/overview.ts +8 -0
- package/src/preview/terminal.ts +15 -5
- package/src/project/project-store.ts +20 -0
- package/src/prompt-cache/openai.ts +3 -0
- package/src/prompt-cache/types.ts +5 -0
- package/src/prompt-enhance/enhance.ts +23 -0
- package/src/release-loop/auto-start.ts +7 -5
- package/src/release-loop/checklist.ts +11 -1
- package/src/release-loop/gate-shards.ts +4 -0
- package/src/release-loop/light-rc.ts +84 -13
- package/src/release-loop/merged-pr-checklist.ts +35 -5
- package/src/release-loop/placement.ts +16 -1
- package/src/release-loop/rehearsal.ts +1 -1
- package/src/requirements/requirement-ledger.ts +536 -0
- package/src/retro/daily.ts +5 -5
- package/src/seat-loop/duty-ledger.ts +64 -0
- package/src/seat-loop/seat-loop.ts +32 -10
- package/src/self-dev/decompose.ts +37 -3
- package/src/self-dev/dev-cli.ts +44 -10
- package/src/self-dev/dev-pipeline.ts +39 -9
- package/src/self-dev/draft-residue.ts +27 -5
- package/src/self-dev/draft-sweep.ts +151 -0
- package/src/self-dev/fabric-decompose-adapter.ts +9 -2
- package/src/self-dev/graph-journey-route.ts +6 -0
- package/src/self-dev/orchestrate-cli.ts +25 -3
- package/src/self-dev/orchestrate.ts +41 -6
- package/src/self-dev/run-supervisor.ts +218 -15
- package/src/self-dev/run-types.ts +13 -0
- package/src/self-dev/supervisor-verdict-edges.ts +1 -0
- package/src/self-implement/budget-gate.ts +53 -13
- package/src/self-implement/child-context-composition.ts +139 -0
- package/src/self-implement/child-llm-preference.ts +13 -5
- package/src/self-implement/claude-acp-implement.ts +67 -0
- package/src/self-implement/flex-signals.ts +59 -0
- package/src/self-implement/frozen-merges.ts +8 -3
- package/src/self-implement/gate-cli.ts +29 -10
- package/src/self-implement/gate-remote.ts +4 -1
- package/src/self-implement/goal-author-decompose.ts +10 -2
- package/src/self-implement/goal-author.ts +36 -11
- package/src/self-implement/goal-new-paths.ts +42 -0
- package/src/self-implement/graph-overlay-condition.ts +28 -0
- package/src/self-implement/graph-overlay-yaml.ts +41 -7
- package/src/self-implement/graph-templates.ts +33 -1
- package/src/self-implement/graph-yaml.ts +56 -0
- package/src/self-implement/heal-intake.ts +5 -1
- package/src/self-implement/host-regate.ts +124 -30
- package/src/self-implement/importer-test-index.ts +3 -1
- package/src/self-implement/l8-merge-queue.ts +80 -2
- package/src/self-implement/merge-train.ts +19 -0
- package/src/self-implement/off-diff-evidence.ts +40 -1
- package/src/self-implement/orchestrator.ts +230 -32
- package/src/self-implement/premise-review.ts +159 -0
- package/src/self-implement/regate-detail.ts +79 -0
- package/src/self-implement/review-deferred-to-host.ts +21 -0
- package/src/self-implement/rework-budget-judgment.ts +23 -3
- package/src/self-implement/running-runs.ts +75 -5
- package/src/self-implement/scope-adjacency.ts +23 -0
- package/src/self-implement/seams.ts +89 -8
- package/src/self-implement/self-implement-cli.ts +9 -4
- package/src/self-implement/stop-autoheal.ts +69 -2
- package/src/session-runtime/retry-policy.ts +2 -1
- package/src/skills/tools/agent.ts +16 -1
- package/src/skills/tools/persistent-grounding.ts +11 -1
- package/src/skills/tools/shell.ts +33 -1
- package/src/steward/launch.ts +5 -4
- package/src/steward/rejudge-tick.ts +142 -0
- package/src/steward/triage-budget.ts +62 -0
- package/src/steward/triage.ts +83 -22
- package/src/task-agent/actions.ts +62 -5
- package/src/task-agent/board.ts +92 -3
- package/src/task-agent/card-evidence.ts +88 -1
- package/src/task-agent/completion-evidence.ts +5 -0
- package/src/task-agent/cover.ts +166 -3
- package/src/task-agent/judge.ts +16 -0
- package/src/task-agent/land-order-ledger.ts +95 -0
- package/src/task-agent/live-move-history.ts +87 -1
- package/src/task-agent/live-moves.ts +350 -20
- package/src/task-agent/parent-host.ts +27 -3
- package/src/task-agent/rejudge-on-head.ts +223 -24
- package/src/task-agent/review-prior-fix.ts +146 -0
- package/src/task-agent/review-result-capture.ts +3 -1
- package/src/task-agent/run-adopt.ts +136 -0
- package/src/task-agent/shadow.ts +65 -9
- package/src/task-agent/task-hand.ts +57 -7
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +38 -5
- package/src/task-orchestrator/surfaces/pod-bedrock-child.ts +74 -0
- package/src/task-orchestrator/surfaces/pod-child-default.ts +50 -0
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +14 -1
- package/src/task-orchestrator/surfaces/pod-command-job.ts +14 -0
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +79 -6
- package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +122 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +17 -5
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +11 -5
- package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +23 -0
- package/src/task-orchestrator/surfaces/pod-pool.ts +73 -4
- package/src/task-orchestrator/surfaces/pod-zai-child.ts +101 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +432 -35
- package/src/task-orchestrator/surfaces/self-implement.ts +19 -1
- package/src/typecheck-ratchet.ts +1 -0
- package/src/user-config.ts +69 -15
- package/src/ux-sim/fault-cred-expiry.ts +100 -0
- package/src/ux-sim/fault-pod-death.ts +74 -0
- package/src/ux-sim/fault-pool-cap.ts +81 -0
- package/src/version/packed-revision.json +1 -1
- package/src/webclone/qa-table.ts +22 -0
- package/src/workflow-runtime/triggers/registry.ts +59 -0
- package/src/workflow-runtime/triggers/webhook-source.ts +35 -5
- package/apps/pwa/out/_next/static/chunks/0a09e062-34f747a17d8d8c2e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +0 -77
- package/apps/pwa/out/_next/static/chunks/1325-dc3f3c21eb181cb4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +0 -34
- package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +0 -24
- package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1669-da843ed73aa301f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +0 -36
- package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +0 -122
- package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +0 -62
- package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/272-b23d2e92161d11fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +0 -149
- package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3961-fbef064c213b2b18.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +0 -309
- package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5313.1697309c532b9856.js +0 -2
- package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +0 -74
- package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +0 -64
- package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +0 -32
- package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +0 -93
- package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +0 -148
- package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +0 -226
- package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +0 -27
- package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +0 -115
- package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +0 -8
- package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +0 -23
- package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +0 -90
- package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +0 -94
- package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +0 -41
- package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +0 -287
- package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +0 -79
- package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +0 -104
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5341ac96203a983.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-6168a7c43e6ef8f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-2bd9ce9c020d02d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-745d9b6c015076f8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.js +0 -1
- package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-b2763b10dc6b3836.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +0 -1
- package/apps/pwa/out/_next/static/css/5619d59e87eddf66.css +0 -1
- /package/apps/pwa/out/_next/static/{rfkMm4movqkqMebBrCXiR → dRS6lEhSRRBr1abbzp7fJ}/_ssgManifest.js +0 -0
package/src/llm/bedrock.ts
CHANGED
|
@@ -8,7 +8,18 @@
|
|
|
8
8
|
// 📏 출처: https://platform.claude.com/docs/en/build-with-claude/claude-in-amazon-bedrock (2026-10-10 확인)
|
|
9
9
|
// — *"Unlike the InvokeModel-based integration, this endpoint uses standard SSE streaming and the same
|
|
10
10
|
// request body shape as Anthropic's first-party API."* ⇒ 몸(`cache_control` 포함)·SSE 파서를 «바이트 그대로» 재사용한다.
|
|
11
|
-
// (레거시 InvokeModel 은 AWS event-stream 이진 인코딩이라 별도 디코더가
|
|
11
|
+
// (레거시 InvokeModel 은 AWS event-stream 이진 인코딩이라 별도 디코더가 필요하다.)
|
|
12
|
+
//
|
|
13
|
+
// ⭐ BEDROCK-RUNTIME-PATH(2026-10-11) — «경로» 둘. 모델 표의 `route` 칸이 고른다.
|
|
14
|
+
// · `mantle` = 위 메시지 엔드포인트. 📏 10-11 실측: mantle `GET /v1/models` 에 Sonnet/Haiku 5.5 가 «없다»
|
|
15
|
+
// (ap-northeast-2 = sonnet-5 뿐 · us-east-1 = opus-5-5·sonnet-5·haiku-4-5) ⇒ `anthropic.claude-sonnet-5-5` 는 404.
|
|
16
|
+
// · `runtime` = `bedrock-runtime.{region}.amazonaws.com/model/{id}/invoke-with-response-stream` · SigV4 서비스 `bedrock`.
|
|
17
|
+
// 몸은 같은 Anthropic Messages 꼴(`anthropic_version: bedrock-2023-05-31` · `model`·`stream` 은 빼고 URL 로) —
|
|
18
|
+
// `cache_control` 자리가 mantle 과 «같다». 응답은 eventstream 이진 프레임(`./bedrock-eventstream.ts`).
|
|
19
|
+
// 📏 전역 추론 프로필 `global.anthropic.claude-{sonnet,haiku}-5-5` 가 ap-northeast-2 에서 200.
|
|
20
|
+
// · `mantle-openai` = 같은 mantle 호스트의 OpenAI chat.completions 호환 엔드포인트(BEDROCK-MODELS-ALL · 비-Anthropic 모델).
|
|
21
|
+
// 경로 `/openai/v1/chat/completions`(OpenAI 계열) · `/v1/chat/completions`(그 밖) · SigV4 서비스 `bedrock-mantle`
|
|
22
|
+
// · 고정 리전 us-east-1(📏 MK 실측 6/6 200) · 응답은 OpenAI SSE.
|
|
12
23
|
//
|
|
13
24
|
// ⛔ 자격 «값»은 이 모듈 밖으로 나가지 않는다 — 로그·에러·반환값 어디에도 싣지 않는다(값 미열람 원칙).
|
|
14
25
|
// 가용 판정은 «신호가 있나»(이름·파일 존재)만 보고, 실제 해석은 SDK 기본 자격 체인이 한다.
|
|
@@ -20,31 +31,81 @@ import { join } from 'node:path';
|
|
|
20
31
|
/** 사람용 별칭 접두. `bedrock/claude-sonnet-5-5` → `anthropic.claude-sonnet-5-5`. */
|
|
21
32
|
const BEDROCK_ALIAS_PREFIX = 'bedrock/';
|
|
22
33
|
|
|
34
|
+
/** runtime(InvokeModel*) 몸의 `anthropic_version` 값 — Bedrock 의 Anthropic Messages 고정값. */
|
|
35
|
+
const BEDROCK_RUNTIME_ANTHROPIC_VERSION = 'bedrock-2023-05-31';
|
|
36
|
+
|
|
37
|
+
/** runtime 경로의 SigV4 서명 서비스 이름(`bedrock-runtime` 호스트도 서명 스코프는 `bedrock`). */
|
|
38
|
+
const BEDROCK_RUNTIME_SIGV4_SERVICE = 'bedrock';
|
|
39
|
+
|
|
23
40
|
/** Bedrock 메시지 엔드포인트의 `anthropic-version` 헤더값(출처 문서의 cURL 예시 그대로). */
|
|
24
41
|
const BEDROCK_ANTHROPIC_VERSION = '2023-06-01';
|
|
25
42
|
|
|
26
43
|
/** SigV4 서명 서비스 이름(출처 문서 cURL `--aws-sigv4 "aws:amz:us-east-1:bedrock-mantle"`). */
|
|
27
44
|
const BEDROCK_SIGV4_SERVICE = 'bedrock-mantle';
|
|
28
45
|
|
|
46
|
+
/** 어느 엔드포인트로 보내나 — `mantle`(Anthropic 메시지 엔드포인트) · `runtime`(InvokeModelWithResponseStream) ·
|
|
47
|
+
* `mantle-openai`(같은 mantle 호스트의 OpenAI chat.completions 호환 엔드포인트 — 비-Anthropic 모델). */
|
|
48
|
+
export type BedrockRoute = 'mantle' | 'runtime' | 'mantle-openai';
|
|
49
|
+
|
|
50
|
+
/** mantle-openai 경로 조각 — OpenAI 계열(`openai.gpt-6-*`)만 `/openai` 접두, 나머지는 `/v1`. */
|
|
51
|
+
export type BedrockOpenAIPath = '/openai/v1/chat/completions' | '/v1/chat/completions';
|
|
52
|
+
|
|
29
53
|
export interface BedrockModelEntry {
|
|
30
|
-
/** 와이어 id(`model` 필드). */
|
|
54
|
+
/** 와이어 id(mantle = `model` 필드 · runtime = URL 의 모델/추론 프로필 id). */
|
|
31
55
|
readonly id: string;
|
|
32
56
|
/** 같은 모델의 1st-party id — 계열 판정(adaptive thinking·vision·temperature)에 쓴다. */
|
|
33
57
|
readonly canonical: string;
|
|
34
58
|
readonly tier: 'cheap' | 'balanced' | 'flagship';
|
|
35
59
|
readonly supportsThinking: boolean;
|
|
60
|
+
/** ⭐ 경로 칸 — 이 id 를 «실제로 내는» 엔드포인트. mantle 에 없는 id 를 mantle 로 보내지 않는다. */
|
|
61
|
+
readonly route: BedrockRoute;
|
|
62
|
+
/** `route: 'mantle-openai'` 행만 — chat.completions 경로. */
|
|
63
|
+
readonly openaiPath?: BedrockOpenAIPath;
|
|
64
|
+
/** `route: 'mantle-openai'` 행만 — 이 모델을 내는 고정 리전(📏 MK 실측 us-east-1 mantle 6/6 200). 사용자 리전과 무관하다. */
|
|
65
|
+
readonly region?: string;
|
|
36
66
|
}
|
|
37
67
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
68
|
+
const MANTLE_OPENAI_REGION = 'us-east-1';
|
|
69
|
+
|
|
70
|
+
function openaiRow(id: string, tier: BedrockModelEntry['tier'], openaiPath: BedrockOpenAIPath): BedrockModelEntry {
|
|
71
|
+
return { id, canonical: id, tier, supportsThinking: false, route: 'mantle-openai', openaiPath, region: MANTLE_OPENAI_REGION };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** ⭐ 모델 표 = «경로» 결정표(BEDROCK-RUNTIME-PATH · 2026-10-11).
|
|
75
|
+
* · 5.5 계열 = 전역 추론 프로필(`global.anthropic.…`) ⊕ runtime — 📏 `aws bedrock list-inference-profiles`(ap-northeast-2)에
|
|
76
|
+
* 셋 다 있고, sonnet/haiku 는 `converse` 200 실측. opus-5-5 는 «목록에 있음»까지만 쟀다(호출 0).
|
|
77
|
+
* · mantle 이 «실제로 내는» 모델(`GET /v1/models` 실측: sonnet-5)은 mantle 그대로.
|
|
78
|
+
* 사람 별칭(`claude-sonnet-5-5`·`bedrock/claude-sonnet-5-5`·접두 없는 `anthropic.claude-sonnet-5-5`)은 canonical 로 이 표를 찾아 `id` 로 푼다.
|
|
79
|
+
* 표 밖 id: 지역/전역 접두(`us.`·`apac.`·`global.`…)가 붙었으면 runtime, 아니면 종전대로 mantle(엔드포인트가 판정). */
|
|
41
80
|
export const BEDROCK_MODELS: readonly BedrockModelEntry[] = [
|
|
42
|
-
{ id: 'anthropic.claude-sonnet-5-5', canonical: 'claude-sonnet-5-5', tier: 'balanced', supportsThinking: true },
|
|
43
|
-
{ id: 'anthropic.claude-haiku-5-5', canonical: 'claude-haiku-5-5', tier: 'cheap', supportsThinking: true },
|
|
44
|
-
{ id: 'anthropic.claude-opus-5-5', canonical: 'claude-opus-5-5', tier: 'flagship', supportsThinking: true },
|
|
81
|
+
{ id: 'global.anthropic.claude-sonnet-5-5', canonical: 'claude-sonnet-5-5', tier: 'balanced', supportsThinking: true, route: 'runtime' },
|
|
82
|
+
{ id: 'global.anthropic.claude-haiku-5-5', canonical: 'claude-haiku-5-5', tier: 'cheap', supportsThinking: true, route: 'runtime' },
|
|
83
|
+
{ id: 'global.anthropic.claude-opus-5-5', canonical: 'claude-opus-5-5', tier: 'flagship', supportsThinking: true, route: 'runtime' },
|
|
84
|
+
{ id: 'anthropic.claude-sonnet-5', canonical: 'claude-sonnet-5', tier: 'balanced', supportsThinking: true, route: 'mantle' },
|
|
85
|
+
// 비-Anthropic = mantle OpenAI 호환 경로(IAM 변경 없이 가능). runtime Converse 모델(GLM 5.3·Kimi K3·Grok 4.7)은 IAM 결정 뒤라 «아직 없다».
|
|
86
|
+
openaiRow('openai.gpt-6-sol', 'flagship', '/openai/v1/chat/completions'),
|
|
87
|
+
openaiRow('openai.gpt-6-luna', 'balanced', '/openai/v1/chat/completions'),
|
|
88
|
+
openaiRow('zai.glm-5', 'flagship', '/v1/chat/completions'),
|
|
89
|
+
openaiRow('zai.glm-4.7-flash', 'cheap', '/v1/chat/completions'),
|
|
90
|
+
openaiRow('deepseek.v3.2', 'balanced', '/v1/chat/completions'),
|
|
91
|
+
openaiRow('moonshotai.kimi-k2.5', 'balanced', '/v1/chat/completions'),
|
|
92
|
+
openaiRow('qwen.qwen3-coder-next', 'balanced', '/v1/chat/completions'),
|
|
93
|
+
openaiRow('minimax.minimax-m2.5', 'cheap', '/v1/chat/completions'),
|
|
94
|
+
openaiRow('mistral.devstral-2-123b', 'balanced', '/v1/chat/completions'),
|
|
45
95
|
];
|
|
46
96
|
|
|
47
|
-
export const BEDROCK_DEFAULT_MODEL = 'anthropic.claude-sonnet-5-5';
|
|
97
|
+
export const BEDROCK_DEFAULT_MODEL = 'global.anthropic.claude-sonnet-5-5';
|
|
98
|
+
|
|
99
|
+
/** 지역/전역 추론 프로필 접두(`global.`·`us.`·`eu.`·`apac.`·`jp.`·`au.` …) — 이 꼴은 runtime 만 받는다. */
|
|
100
|
+
const BEDROCK_INFERENCE_PROFILE_PREFIX = /^[a-z]{2,6}\.anthropic\./i;
|
|
101
|
+
|
|
102
|
+
/** 와이어 id → 경로. 표에 있으면 표의 칸, 추론 프로필 접두면 runtime, 그 밖은 종전대로 mantle. */
|
|
103
|
+
export function bedrockRouteFor(wireId: string): BedrockRoute {
|
|
104
|
+
const id = wireId.trim();
|
|
105
|
+
const entry = BEDROCK_MODELS.find((m) => m.id === id);
|
|
106
|
+
if (entry) return entry.route;
|
|
107
|
+
return BEDROCK_INFERENCE_PROFILE_PREFIX.test(id) ? 'runtime' : 'mantle';
|
|
108
|
+
}
|
|
48
109
|
|
|
49
110
|
/** 지역/전역 추론 프로필 접두(`us.`·`eu.`·`jp.`·`au.`·`apac.`·`global.`)를 허용한다. */
|
|
50
111
|
const BEDROCK_CLAUDE_ID = /^(?:[a-z]{2,6}\.)?anthropic\.claude-[a-z0-9.\-:]+$/i;
|
|
@@ -54,19 +115,28 @@ export function isBedrockModelId(model: string | undefined): boolean {
|
|
|
54
115
|
const m = (model ?? '').trim();
|
|
55
116
|
if (!m) return false;
|
|
56
117
|
if (m.toLowerCase().startsWith(BEDROCK_ALIAS_PREFIX)) return true;
|
|
57
|
-
return BEDROCK_CLAUDE_ID.test(m);
|
|
118
|
+
return BEDROCK_CLAUDE_ID.test(m) || BEDROCK_MODELS.some((e) => e.route === 'mantle-openai' && e.id === m);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** 와이어 id → 고정 리전(mantle-openai 행만). 그 밖은 `fallback`(사용자 리전). */
|
|
122
|
+
export function bedrockRegionFor(wireId: string, fallback: string): string {
|
|
123
|
+
const entry = BEDROCK_MODELS.find((m) => m.id === wireId.trim());
|
|
124
|
+
return entry?.route === 'mantle-openai' && entry.region ? entry.region : fallback;
|
|
58
125
|
}
|
|
59
126
|
|
|
60
|
-
/** 입력 → 와이어 id. `bedrock/claude-x` · `claude-x`(provider=bedrock 일 때)
|
|
61
|
-
*
|
|
127
|
+
/** 입력 → 와이어 id. `bedrock/claude-x` · `claude-x`(provider=bedrock 일 때) · 접두 없는 `anthropic.claude-x`
|
|
128
|
+
* 는 표(canonical)에 있으면 표의 `id`(예 5.5 → `global.anthropic.…` runtime), 없으면 `anthropic.claude-x`.
|
|
129
|
+
* 지역/전역 접두가 «이미» 붙은 id 는 그대로(데이터 거주 선택 보존). 그 밖은 그대로 돌려준다(엔드포인트가 판정한다). */
|
|
62
130
|
export function resolveBedrockModelId(model: string | undefined): string {
|
|
63
131
|
const raw = (model ?? '').trim();
|
|
64
132
|
if (!raw) return BEDROCK_DEFAULT_MODEL;
|
|
65
133
|
let m = raw;
|
|
66
134
|
if (m.toLowerCase().startsWith(BEDROCK_ALIAS_PREFIX)) m = m.slice(BEDROCK_ALIAS_PREFIX.length);
|
|
67
|
-
if (BEDROCK_CLAUDE_ID.test(m)) return m;
|
|
68
|
-
|
|
69
|
-
return m;
|
|
135
|
+
if (BEDROCK_INFERENCE_PROFILE_PREFIX.test(m) && BEDROCK_CLAUDE_ID.test(m)) return m;
|
|
136
|
+
const bare = /^anthropic\.claude-/i.test(m) ? m.slice('anthropic.'.length) : /^claude-/i.test(m) ? m : undefined;
|
|
137
|
+
if (bare === undefined) return m;
|
|
138
|
+
const entry = BEDROCK_MODELS.find((e) => e.canonical === bare.toLowerCase());
|
|
139
|
+
return entry ? entry.id : `anthropic.${bare}`;
|
|
70
140
|
}
|
|
71
141
|
|
|
72
142
|
/** 와이어 id → 1st-party 꼴(`claude-…`). 계열 판정 헬퍼(adaptive·vision·temperature)가 이 꼴을 안다. */
|
|
@@ -77,7 +147,7 @@ export function bedrockCanonicalClaudeId(model: string | undefined): string {
|
|
|
77
147
|
|
|
78
148
|
/** 표의 모델을 찾는다 — 지역/전역 추론 프로필 접두(`us.anthropic.…`)도 같은 모델로 본다(계열은 접두를 뗀 꼴로). */
|
|
79
149
|
export function findBedrockModel(id: string): BedrockModelEntry | undefined {
|
|
80
|
-
const canonical = bedrockCanonicalClaudeId(id.trim());
|
|
150
|
+
const canonical = bedrockCanonicalClaudeId(id.trim()).toLowerCase();
|
|
81
151
|
return BEDROCK_MODELS.find((m) => m.canonical === canonical);
|
|
82
152
|
}
|
|
83
153
|
|
|
@@ -217,6 +287,14 @@ export function bedrockAvailable(deps: BedrockEnvDeps = {}): boolean {
|
|
|
217
287
|
return resolveBedrockRegion(deps) !== undefined;
|
|
218
288
|
}
|
|
219
289
|
|
|
290
|
+
/** 응답 본문의 AWS 식별자(ARN · 12자리 계정 번호)를 가린다 — 403 `permission_error` 본문이 IAM 주체 ARN 을 그대로 싣는다
|
|
291
|
+
* (📏 BEDROCK-CHECK 10-11 실호출). `redactSecrets` 는 ARN 을 모른다 ⇒ 에러 문면·로그로 계정이 새지 않게 여기서 한 번 더 지운다. */
|
|
292
|
+
export function redactAwsIdentifiers(text: string): string {
|
|
293
|
+
return text
|
|
294
|
+
.replace(/arn:aws[a-z-]*:[^\s"',;]*/gi, 'arn:<redacted>')
|
|
295
|
+
.replace(/(?<![0-9])[0-9]{12}(?![0-9])/g, '<account>');
|
|
296
|
+
}
|
|
297
|
+
|
|
220
298
|
/** SDK 자격 체인이 내는 «고정» 에러 이름 — 이것만 메시지·로그에 싣는다. 그 밖은 `CredentialResolutionError`. */
|
|
221
299
|
const KNOWN_CREDENTIAL_ERROR_NAMES: ReadonlySet<string> = new Set([
|
|
222
300
|
'CredentialsProviderError', 'ProviderError', 'TokenProviderError', 'TimeoutError',
|
|
@@ -252,6 +330,49 @@ export function bedrockMessagesUrl(region: string): string {
|
|
|
252
330
|
return url;
|
|
253
331
|
}
|
|
254
332
|
|
|
333
|
+
/** ⭐ mantle OpenAI 호환 URL — 경로는 모델 표의 `openaiPath` 칸이 정한다(표 밖 id 는 거부 · 호스트는 메시지 엔드포인트와 같다). */
|
|
334
|
+
export function bedrockMantleOpenAIUrl(region: string, modelId: string): string {
|
|
335
|
+
const valid = validBedrockRegion(region);
|
|
336
|
+
if (!valid) throw new Error('Bedrock: 리전 값이 AWS 리전 꼴이 아니다 — 요청을 만들지 않는다');
|
|
337
|
+
const entry = BEDROCK_MODELS.find((m) => m.id === modelId.trim());
|
|
338
|
+
if (entry?.route !== 'mantle-openai' || !entry.openaiPath) throw new Error('Bedrock: 모델이 mantle OpenAI 경로 표에 없다 — 요청을 만들지 않는다');
|
|
339
|
+
const host = `bedrock-mantle.${valid}.api.aws`;
|
|
340
|
+
const url = `https://${host}${entry.openaiPath}`;
|
|
341
|
+
const u = new URL(url);
|
|
342
|
+
if (u.protocol !== 'https:' || u.hostname !== host || u.username || u.password || u.search || u.hash) {
|
|
343
|
+
throw new Error('Bedrock: 요청 호스트가 Bedrock 엔드포인트가 아니다 — 요청을 만들지 않는다');
|
|
344
|
+
}
|
|
345
|
+
return url;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/** ⭐ runtime 경로 URL — 리전 꼴 검증 ⊕ 모델 id 꼴 검증 ⊕ 호스트 이중 확인(자격을 붙이기 «전»).
|
|
349
|
+
* 모델 id 는 경로 조각이라 `/`·`?`·`#`·`@` 등을 받지 않는다(추론 프로필 id 꼴 `[A-Za-z0-9._:-]` 만). */
|
|
350
|
+
const BEDROCK_RUNTIME_MODEL_ID_SHAPE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$/;
|
|
351
|
+
|
|
352
|
+
export function bedrockRuntimeInvokeUrl(region: string, modelId: string): string {
|
|
353
|
+
const valid = validBedrockRegion(region);
|
|
354
|
+
if (!valid) throw new Error('Bedrock: 리전 값이 AWS 리전 꼴이 아니다 — 요청을 만들지 않는다');
|
|
355
|
+
const id = modelId.trim();
|
|
356
|
+
if (!BEDROCK_RUNTIME_MODEL_ID_SHAPE.test(id)) throw new Error('Bedrock: 모델 id 가 추론 프로필 id 꼴이 아니다 — 요청을 만들지 않는다');
|
|
357
|
+
const host = `bedrock-runtime.${valid}.amazonaws.com`;
|
|
358
|
+
const url = `https://${host}/model/${encodeURIComponent(id)}/invoke-with-response-stream`;
|
|
359
|
+
const u = new URL(url);
|
|
360
|
+
if (u.protocol !== 'https:' || u.hostname !== host || u.username || u.password || u.search || u.hash) {
|
|
361
|
+
throw new Error('Bedrock: 요청 호스트가 Bedrock runtime 엔드포인트가 아니다 — 요청을 만들지 않는다');
|
|
362
|
+
}
|
|
363
|
+
return url;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/** 서명 «직전» 호스트 확인 — 경로별로 허용 호스트는 «하나»다. 아니면 자격을 붙이지 않는다. */
|
|
367
|
+
export function assertBedrockHost(url: string, region: string, route: BedrockRoute): void {
|
|
368
|
+
const valid = validBedrockRegion(region);
|
|
369
|
+
const u = new URL(url);
|
|
370
|
+
const want = route === 'runtime' ? `bedrock-runtime.${valid}.amazonaws.com` : `bedrock-mantle.${valid}.api.aws`;
|
|
371
|
+
if (!valid || u.protocol !== 'https:' || u.hostname !== want || u.username || u.password) {
|
|
372
|
+
throw new Error('Bedrock: 요청 호스트가 Bedrock 엔드포인트가 아니다 — 자격을 붙이지 않는다');
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
255
376
|
export interface SignedBedrockRequest {
|
|
256
377
|
url: string;
|
|
257
378
|
headers: Record<string, string>;
|
|
@@ -265,16 +386,18 @@ export type BedrockSigner = (input: {
|
|
|
265
386
|
headers: Record<string, string>;
|
|
266
387
|
body: string;
|
|
267
388
|
credentials: BedrockCredentials;
|
|
389
|
+
/** SigV4 서비스 — mantle `bedrock-mantle` · runtime `bedrock`. 없으면 mantle. */
|
|
390
|
+
service?: string;
|
|
268
391
|
}) => Promise<Record<string, string>>;
|
|
269
392
|
|
|
270
|
-
export const defaultBedrockSigner: BedrockSigner = async ({ url, region, headers, body, credentials }) => {
|
|
393
|
+
export const defaultBedrockSigner: BedrockSigner = async ({ url, region, headers, body, credentials, service }) => {
|
|
271
394
|
const [{ SignatureV4 }, { Hash }] = await Promise.all([
|
|
272
395
|
import('@smithy/signature-v4'),
|
|
273
396
|
import('@smithy/hash-node'),
|
|
274
397
|
]);
|
|
275
398
|
const u = new URL(url);
|
|
276
399
|
const signer = new SignatureV4({
|
|
277
|
-
service: BEDROCK_SIGV4_SERVICE,
|
|
400
|
+
service: service ?? BEDROCK_SIGV4_SERVICE,
|
|
278
401
|
region,
|
|
279
402
|
credentials,
|
|
280
403
|
sha256: Hash.bind(null, 'sha256'),
|
|
@@ -292,32 +415,55 @@ export const defaultBedrockSigner: BedrockSigner = async ({ url, region, headers
|
|
|
292
415
|
return out;
|
|
293
416
|
};
|
|
294
417
|
|
|
295
|
-
/**
|
|
418
|
+
/** runtime 몸 — mantle 몸에서 `model`(URL 로 간다)·`stream`(엔드포인트가 정한다)을 빼고 `anthropic_version` 을 앞에 둔다.
|
|
419
|
+
* 나머지 칸(`messages`·`system`·`tools`·`cache_control` 자리)은 «바이트 그대로» 같다. */
|
|
420
|
+
export function bedrockRuntimeBody(body: Record<string, unknown>): Record<string, unknown> {
|
|
421
|
+
const { model: _model, stream: _stream, ...rest } = body;
|
|
422
|
+
return { anthropic_version: BEDROCK_RUNTIME_ANTHROPIC_VERSION, ...rest };
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/** 요청 한 건을 조립·서명한다. 베어러 토큰(`AWS_BEARER_TOKEN_BEDROCK`)이 있으면 mantle 은 `x-api-key`(출처 문서 «Bearer tokens»),
|
|
426
|
+
* runtime 은 `authorization: Bearer`(Bedrock API 키 규약).
|
|
427
|
+
* mantle-openai 는 OpenAI 호환 엔드포인트 규약대로 베어러를 `authorization: Bearer` 로 보낸다(몸은 mantle 과 같은 `{...body, stream:true}`).
|
|
428
|
+
* `route` 가 없으면 몸의 `model` 로 표를 본다(`bedrockRouteFor`). */
|
|
296
429
|
export async function buildSignedBedrockRequest(input: {
|
|
297
430
|
region: string;
|
|
298
431
|
body: Record<string, unknown>;
|
|
299
432
|
env?: Env;
|
|
300
433
|
resolveCredentials?: BedrockCredentialResolver;
|
|
301
434
|
sign?: BedrockSigner;
|
|
435
|
+
route?: BedrockRoute;
|
|
302
436
|
}): Promise<SignedBedrockRequest> {
|
|
303
437
|
const env = input.env ?? process.env;
|
|
304
|
-
const
|
|
305
|
-
|
|
438
|
+
const route = input.route ?? bedrockRouteFor(String(input.body.model ?? ''));
|
|
439
|
+
const url = route === 'runtime'
|
|
440
|
+
? bedrockRuntimeInvokeUrl(input.region, String(input.body.model ?? ''))
|
|
441
|
+
: route === 'mantle-openai'
|
|
442
|
+
? bedrockMantleOpenAIUrl(input.region, String(input.body.model ?? ''))
|
|
443
|
+
: bedrockMessagesUrl(input.region);
|
|
444
|
+
// URL 과 서명 스코프가 «같은» 정규화 리전을 쓴다(URL 빌더가 무효면 이미 던졌다).
|
|
306
445
|
const region = validBedrockRegion(input.region)!;
|
|
307
|
-
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
446
|
+
assertBedrockHost(url, region, route);
|
|
447
|
+
const body = route === 'runtime'
|
|
448
|
+
? JSON.stringify(bedrockRuntimeBody(input.body))
|
|
449
|
+
: JSON.stringify({ ...input.body, stream: true });
|
|
450
|
+
const base: Record<string, string> = route === 'runtime'
|
|
451
|
+
? { 'content-type': 'application/json', accept: 'application/vnd.amazon.eventstream' }
|
|
452
|
+
: route === 'mantle-openai'
|
|
453
|
+
? { 'content-type': 'application/json', accept: 'text/event-stream' }
|
|
454
|
+
: { 'content-type': 'application/json', 'anthropic-version': BEDROCK_ANTHROPIC_VERSION };
|
|
312
455
|
const bearer = env.AWS_BEARER_TOKEN_BEDROCK?.trim();
|
|
313
|
-
if (bearer)
|
|
456
|
+
if (bearer) {
|
|
457
|
+
return { url, headers: route === 'mantle' ? { ...base, 'x-api-key': bearer } : { ...base, authorization: `Bearer ${bearer}` }, body };
|
|
458
|
+
}
|
|
314
459
|
let credentials: BedrockCredentials;
|
|
315
460
|
try {
|
|
316
461
|
credentials = await (input.resolveCredentials ?? defaultBedrockCredentialResolver)();
|
|
317
462
|
} catch (err) {
|
|
318
463
|
throw new BedrockCredentialsUnresolvedError(sanitizeCredentialErrorName(err));
|
|
319
464
|
}
|
|
320
|
-
const
|
|
465
|
+
const service = route === 'runtime' ? BEDROCK_RUNTIME_SIGV4_SERVICE : BEDROCK_SIGV4_SERVICE;
|
|
466
|
+
const headers = await (input.sign ?? defaultBedrockSigner)({ url, region, headers: base, body, credentials, service });
|
|
321
467
|
return { url, headers, body };
|
|
322
468
|
}
|
|
323
469
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** OpenRouter(`openrouter/…`) GLM·Kimi·Qwen 전용 도구 호출 규율 — 다른 군 상수와 합성하지 않는 독립 상수.
|
|
2
|
+
*
|
|
3
|
+
* 2026-10-11 GLM-PROMPT-TUNE 첫 조각: `llm.ts` 동결(RFC #25983)을 위해 상수를 이 파일로 옮겼다.
|
|
4
|
+
* 줄 둘을 추가했다 — 실측 약점 둘을 겨냥한다:
|
|
5
|
+
* ⑴ 그라운딩 비교 8회 중 GLM 3회 전부 «Grep 으로만 확인하고 Read 는 안 했다»고 스스로 적고
|
|
6
|
+
* 그 경로를 증거로 써 grounding-evidence 기각
|
|
7
|
+
* ⑵ 상 칸에서 PR 없이 라운드만 도는 no-progress(부검반 ×26)
|
|
8
|
+
* 다른 군(codex·grok·local·claude·gemini·gpt·other)의 요청 바이트는 불변 — 이 상수는
|
|
9
|
+
* open-weight 계열에만 주입된다(`TOOL_DISCIPLINE_BY_FAMILY`).
|
|
10
|
+
*
|
|
11
|
+
* ⛔ `llm.ts` 의 `selectIntentClassificationMessages` 가 이 상수와 «정확 일치»로 분류기를
|
|
12
|
+
* 걸러 내므로, 주입부는 상수를 그대로 싣는다(합성 금지). */
|
|
13
|
+
export const OPEN_WEIGHT_TOOL_DISCIPLINE = [
|
|
14
|
+
'[open-weight tool-use discipline]',
|
|
15
|
+
'- 도구로 할 수 있는 일은 이번 응답에서 바로 도구를 호출하라. "먼저 읽겠다" 또는 "확인하겠다" 같은 계획만 말하고 응답을 끝내지 마라.',
|
|
16
|
+
'- 작업을 시작하는 첫 응답에는 도구 호출이 하나 이상 있어야 한다.',
|
|
17
|
+
'- 도구 호출 인자는 해당 도구의 스키마에 맞는 JSON 으로 내라.',
|
|
18
|
+
'- 충분한 근거가 모이면 도구 호출 없이 최종 답을 평문으로 써서 끝내라.',
|
|
19
|
+
'- 증거·근거로 적는 파일은 이번 작업에서 Read 로 연 파일만 — Grep·Glob 결과만으로 내용을 단정하지 마라.',
|
|
20
|
+
'- 구현을 끝냈다고 말하기 전에 바꾼 파일과 돌린 시험 명령·결과를 적어라.',
|
|
21
|
+
].join('\n');
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// OR-BYOK-COST (2026-10-11) — OpenRouter BYOK(Bring Your Own Key) 호출의 «실비용»을 원장에 싣는다.
|
|
2
|
+
//
|
|
3
|
+
// S: OpenRouter 계정에 상류 키(예: OpenAI)가 붙어 있으면 그 호출은 BYOK 로 라우팅된다. 응답 `usage` 는
|
|
4
|
+
// `is_byok: true` · `cost: 0`(OR 청구) · `cost_details.upstream_inference_cost: <USD>`(상류 키로 실제 청구)로 온다
|
|
5
|
+
// (UX 실측 10-11 · `openai/gpt-6-luna` · provider=OpenAI).
|
|
6
|
+
// C: elanous 는 `usage.cost` 만 읽었다 ⇒ BYOK 실비용이 원장(`usdKnown`)에서 사라지고 벤치·롤업 $ 가 0 으로 낮게 잡혔다.
|
|
7
|
+
// A: 파서가 `is_byok` ⊕ `upstream_inference_cost` 를 읽고(이 모듈), 비용 판정이 «OR 청구 + 상류 청구»를
|
|
8
|
+
// `kind:'actual'` 로 낸다(출처 `costSource:'byok-upstream'` 와 두 몫을 곁에 남긴다).
|
|
9
|
+
// ⛔ 상류 칸이 없거나 숫자가 아니면 «미상» — 0 으로 가정하지 않는다(`kind:'partial'` · 롤업이 unknownCostCalls 로 센다).
|
|
10
|
+
|
|
11
|
+
import { debug } from '../debug/log.js';
|
|
12
|
+
|
|
13
|
+
/** 파서가 `LLMUsage` 에 더하는 BYOK 칸. 비-BYOK 응답이면 «빈 객체»(종전 바이트 그대로). */
|
|
14
|
+
export interface OpenRouterByokUsageFields {
|
|
15
|
+
/** OpenRouter `usage.is_byok === true` — 상류 키로 청구된 호출. */
|
|
16
|
+
byok?: true;
|
|
17
|
+
/** OpenRouter `usage.cost_details.upstream_inference_cost` — 상류 키로 실제 청구된 USD. 칸이 없거나 숫자가 아니면 없다(=미상). */
|
|
18
|
+
upstreamCostUsd?: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function finiteNonNegative(v: unknown): v is number {
|
|
22
|
+
return typeof v === 'number' && Number.isFinite(v) && v >= 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** OpenAI 호환 응답(스트림 마지막 청크 · 비스트림 본문 모두 `usage` 가 최상위에 있다)에서 BYOK 칸을 읽는다.
|
|
26
|
+
* ⛔ 관측에 키 값을 넣지 않는다 — 모델·상류 provider·금액만. */
|
|
27
|
+
export function readOpenRouterByokUsage(event: unknown): OpenRouterByokUsageFields {
|
|
28
|
+
if (!event || typeof event !== 'object') return {};
|
|
29
|
+
const e = event as { usage?: unknown; model?: unknown; provider?: unknown };
|
|
30
|
+
const u = e.usage;
|
|
31
|
+
if (!u || typeof u !== 'object') return {};
|
|
32
|
+
const r = u as { is_byok?: unknown; cost_details?: unknown };
|
|
33
|
+
if (r.is_byok !== true) return {};
|
|
34
|
+
const details = r.cost_details && typeof r.cost_details === 'object' ? r.cost_details as { upstream_inference_cost?: unknown } : undefined;
|
|
35
|
+
const upstream = details?.upstream_inference_cost;
|
|
36
|
+
const out: OpenRouterByokUsageFields = { byok: true };
|
|
37
|
+
if (finiteNonNegative(upstream)) out.upstreamCostUsd = upstream;
|
|
38
|
+
try {
|
|
39
|
+
debug.log('llm.openrouter', 'byok-cost', {
|
|
40
|
+
model: typeof e.model === 'string' ? e.model : null,
|
|
41
|
+
provider: typeof e.provider === 'string' ? e.provider : null,
|
|
42
|
+
upstreamCostUsd: out.upstreamCostUsd ?? null,
|
|
43
|
+
});
|
|
44
|
+
} catch { /* 관측 실패가 파싱을 바꾸지 않는다 */ }
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** 스트림 합산(`accumulateUsage`)용 — BYOK 표지는 «한 번이라도» 참이면 참, 상류 금액은 더한다. */
|
|
49
|
+
export function accumulateByokUsage<T extends OpenRouterByokUsageFields>(total: T, received: OpenRouterByokUsageFields): T {
|
|
50
|
+
if (received.byok === true) total.byok = true;
|
|
51
|
+
if (received.upstreamCostUsd !== undefined) total.upstreamCostUsd = (total.upstreamCostUsd ?? 0) + received.upstreamCostUsd;
|
|
52
|
+
return total;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** BYOK 호출의 비용 칸. 두 몫(OR 청구 · 상류 청구)을 모두 알면 `actual`, 하나라도 모르면 `partial`(알려진 몫만 usd). */
|
|
56
|
+
export interface ByokActualCost {
|
|
57
|
+
kind: 'actual';
|
|
58
|
+
model: string;
|
|
59
|
+
/** OR 청구 + 상류 청구. */
|
|
60
|
+
usd: number;
|
|
61
|
+
source: 'provider-reported';
|
|
62
|
+
costSource: 'byok-upstream';
|
|
63
|
+
byok: true;
|
|
64
|
+
orChargeUsd: number;
|
|
65
|
+
upstreamUsd: number;
|
|
66
|
+
estimateUsd?: number;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface ByokPartialCost {
|
|
70
|
+
kind: 'partial';
|
|
71
|
+
model: string;
|
|
72
|
+
/** 알려진 몫만(대개 OR 청구 0). 모르는 몫은 null 칸으로 표시한다 — 롤업은 이 호출을 unknownCostCalls 로 센다. */
|
|
73
|
+
usd: number;
|
|
74
|
+
source: 'provider-reported';
|
|
75
|
+
costSource: 'byok-upstream';
|
|
76
|
+
byok: true;
|
|
77
|
+
orChargeUsd: number | null;
|
|
78
|
+
upstreamUsd: number | null;
|
|
79
|
+
estimateUsd?: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** BYOK 이면 비용 칸을 낸다 — 비-BYOK 이면 null(호출부가 종전 경로로 간다). */
|
|
83
|
+
export function byokCostFor(
|
|
84
|
+
model: string,
|
|
85
|
+
usage: { byok?: unknown; upstreamCostUsd?: unknown; reportedCostUsd?: unknown },
|
|
86
|
+
estimateUsd: number | undefined,
|
|
87
|
+
): ByokActualCost | ByokPartialCost | null {
|
|
88
|
+
if (usage.byok !== true) return null;
|
|
89
|
+
const or = finiteNonNegative(usage.reportedCostUsd) ? usage.reportedCostUsd : null;
|
|
90
|
+
const up = finiteNonNegative(usage.upstreamCostUsd) ? usage.upstreamCostUsd : null;
|
|
91
|
+
const est = estimateUsd !== undefined ? { estimateUsd } : {};
|
|
92
|
+
if (or !== null && up !== null) {
|
|
93
|
+
return { kind: 'actual', model, usd: or + up, source: 'provider-reported', costSource: 'byok-upstream', byok: true, orChargeUsd: or, upstreamUsd: up, ...est };
|
|
94
|
+
}
|
|
95
|
+
return { kind: 'partial', model, usd: (or ?? 0) + (up ?? 0), source: 'provider-reported', costSource: 'byok-upstream', byok: true, orChargeUsd: or, upstreamUsd: up, ...est };
|
|
96
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// OR-DEEPSEEK-TUNE (2026-10-11) — OpenRouter `deepseek/*` 전용 요청 조정.
|
|
2
|
+
//
|
|
3
|
+
// 왜 따로 두나: llm.ts 는 동결(RFC #25983)이라 새 판단은 여기 두고 llm.ts 엔 배선만 남긴다.
|
|
4
|
+
// ⛔ 불변식: 여기 함수들은 «DeepSeek 가 아닌» 모델에 대해 항상 «아무것도 안 바꾼다» 는 값을 돌려준다
|
|
5
|
+
// (빈 객체 · 원래 값 · false) — OpenRouter 의 다른 모델 요청 바이트는 이 모듈 때문에 바뀌지 않는다.
|
|
6
|
+
//
|
|
7
|
+
// 근거(MIT · 패턴만 참고):
|
|
8
|
+
// - openclaw extensions/openrouter/models.ts:56-60 `isOpenRouterDeepSeekV4ModelId` — V4 판정 정규식.
|
|
9
|
+
// - openclaw extensions/openrouter/thinking-policy.ts:8-11 — OpenRouter 의 DeepSeek V4 effort 단계는 off..xhigh
|
|
10
|
+
// (OpenRouter 통일 effort 에 `max` 는 없다 → 이 저장소 실측: `max` 를 보내면 400).
|
|
11
|
+
// - openclaw packages/ai/src/transports/openai-completions-replay.ts:101-127 — «빈» 추론 조각은
|
|
12
|
+
// OpenRouter/DeepSeek 재전송에서 거부된다 ⇒ 빈 placeholder 를 만들지 않고 빈 조각을 걷는다.
|
|
13
|
+
// - opencode packages/opencode/src/provider/transform.ts:303-319 — DeepSeek 는 «모든» assistant 턴에 추론을 요구.
|
|
14
|
+
// (opencode 는 빈 placeholder 를 넣지만 위 openclaw 근거로 여기선 넣지 않는다.)
|
|
15
|
+
// - 상류 고정: 대상 이름은 설정 기본값 `./openrouter-upstream-pins.config.ts` ⊕ 사용자 `llm.openrouter.upstreamPins`.
|
|
16
|
+
// - hermes-agent agent/reasoning_effort.py:130-133 — DeepSeek V4 의 최상위 단계(직결 API 는 `max`) ↔ xhigh.
|
|
17
|
+
|
|
18
|
+
import { debug } from '../debug/log.js';
|
|
19
|
+
import { getCatalog } from '../registry/loader.js';
|
|
20
|
+
import { DEFAULT_OPENROUTER_UPSTREAM_PINS } from './openrouter-upstream-pins.config.js';
|
|
21
|
+
|
|
22
|
+
/** OpenRouter wire 모델(`openrouter/` 를 뗀 id)이 DeepSeek 인가. */
|
|
23
|
+
export function isOpenRouterDeepSeekWireModel(wireModel: string): boolean {
|
|
24
|
+
return wireModel.toLowerCase().startsWith('deepseek/');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** DeepSeek V4 계열(v4-flash · v4.1-flash · v4-pro · 날짜 고정판 · `:variant`)인가. */
|
|
28
|
+
export function isOpenRouterDeepSeekV4WireModel(wireModel: string): boolean {
|
|
29
|
+
return /^deepseek\/deepseek-v4(?:\.\d+)?-/.test(wireModel.toLowerCase());
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type OpenRouterEffort = 'low' | 'medium' | 'high' | 'xhigh';
|
|
33
|
+
|
|
34
|
+
/** DeepSeek V4 effort 표. `xhigh`·`max` → `xhigh`(OpenRouter 가 `max` 를 400 으로 거부) · `off`/모르는 값 → 칸 없음. */
|
|
35
|
+
const DEEPSEEK_V4_EFFORT: Record<string, OpenRouterEffort> = {
|
|
36
|
+
minimal: 'low', low: 'low', medium: 'medium', high: 'high', xhigh: 'xhigh', max: 'xhigh',
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/** DeepSeek V4 이면 그 표의 값(없으면 `null` = 칸 없음), V4 가 아니면 `undefined`(호출자가 기존 표를 쓴다). */
|
|
40
|
+
export function openRouterDeepSeekEffort(wireModel: string, effort: string | undefined): OpenRouterEffort | null | undefined {
|
|
41
|
+
if (!isOpenRouterDeepSeekV4WireModel(wireModel)) return undefined;
|
|
42
|
+
if (effort === undefined || !Object.hasOwn(DEEPSEEK_V4_EFFORT, effort)) return null;
|
|
43
|
+
return DEEPSEEK_V4_EFFORT[effort];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** 카탈로그(YAML · `catalog/models/openrouter/<id>.yaml` 의 `reasoning`)가 정한 DeepSeek 기본 effort.
|
|
47
|
+
* ⛔ 코드에 기본값을 박지 않는다 — 카탈로그(손 레코드)가 정본이다(MK #26055). 없으면 `undefined` → 호출자의 기존 폴백.
|
|
48
|
+
* ⚠️ 발견 폴드가 자동으로 채운 레코드(`discoveryMeta.autoFilled`)는 «능력 추정»(reasoning 칸이 있으면 'high')이라 기본값으로 쓰지 않는다.
|
|
49
|
+
* `lookup` 은 시험용 주입점(미지정 = 실제 카탈로그). */
|
|
50
|
+
export function openRouterDeepSeekCatalogEffort(
|
|
51
|
+
catalogId: string,
|
|
52
|
+
lookup: (id: string) => { reasoning?: string | null; discoveryMeta?: { autoFilled?: boolean } } | undefined
|
|
53
|
+
= (id) => getCatalog().models.get(id),
|
|
54
|
+
): 'low' | 'medium' | 'high' | undefined {
|
|
55
|
+
if (!catalogId.startsWith('openrouter/') || !isOpenRouterDeepSeekWireModel(catalogId.slice('openrouter/'.length))) return undefined;
|
|
56
|
+
let spec: ReturnType<typeof lookup>;
|
|
57
|
+
try { spec = lookup(catalogId); } catch { return undefined; }
|
|
58
|
+
if (!spec || spec.discoveryMeta?.autoFilled === true) return undefined;
|
|
59
|
+
const r = spec.reasoning;
|
|
60
|
+
return r === 'low' || r === 'medium' || r === 'high' ? r : undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** 사용자가 라우팅을 «명시»했는가 — `order`·`only`·`allow_fallbacks` 중 하나라도 있으면 그대로 둔다. */
|
|
64
|
+
function hasExplicitRouting(explicit: unknown): boolean {
|
|
65
|
+
if (!explicit || typeof explicit !== 'object' || Array.isArray(explicit)) return false;
|
|
66
|
+
const e = explicit as Record<string, unknown>;
|
|
67
|
+
return 'order' in e || 'only' in e || 'allow_fallbacks' in e;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** 이 모델의 상류 고정 목록 — 사용자 `llm.openrouter.upstreamPins` 가 기본값(설정 표)을 모델별로 덮는다.
|
|
71
|
+
* 빈 배열·문자열 아닌 값·표에 없음 = 고정 안 함(`undefined`). ⛔ 상류 이름은 여기(코드)가 아니라 설정 기본값에 있다. */
|
|
72
|
+
export function resolveOpenRouterUpstreamPin(
|
|
73
|
+
wireModel: string,
|
|
74
|
+
userPins: unknown,
|
|
75
|
+
defaults: Readonly<Record<string, readonly string[]>> = DEFAULT_OPENROUTER_UPSTREAM_PINS,
|
|
76
|
+
): string[] | undefined {
|
|
77
|
+
const user = userPins && typeof userPins === 'object' && !Array.isArray(userPins) ? userPins as Record<string, unknown> : {};
|
|
78
|
+
const raw = Object.hasOwn(user, wireModel) ? user[wireModel]
|
|
79
|
+
: Object.hasOwn(defaults, wireModel) ? defaults[wireModel] : undefined;
|
|
80
|
+
if (!Array.isArray(raw)) return undefined;
|
|
81
|
+
const order = raw.filter((x): x is string => typeof x === 'string' && x.length > 0);
|
|
82
|
+
return order.length > 0 ? order : undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** 본문 `provider` 칸 덮어쓰기 — `order=<고정 목록>` ⊕ `allow_fallbacks:false`.
|
|
86
|
+
* DeepSeek 가 아니거나 · 사용자가 라우팅을 명시했거나 · 고정 목록이 없으면 `{}`(아무것도 안 싣는다 = OR 기본 라우팅).
|
|
87
|
+
* `base` 는 이미 실린 provider 칸(require_parameters 등 ⊕ 사용자 설정) — 키 순서를 지키려고 그 위에 덮는다. */
|
|
88
|
+
export function openRouterDeepSeekProviderField(
|
|
89
|
+
wireModel: string,
|
|
90
|
+
base: unknown,
|
|
91
|
+
explicit: unknown,
|
|
92
|
+
userPins?: unknown,
|
|
93
|
+
defaults?: Readonly<Record<string, readonly string[]>>,
|
|
94
|
+
): { provider?: Record<string, unknown> } {
|
|
95
|
+
if (!isOpenRouterDeepSeekWireModel(wireModel) || hasExplicitRouting(explicit)) return {};
|
|
96
|
+
const order = resolveOpenRouterUpstreamPin(wireModel, userPins, defaults);
|
|
97
|
+
if (!order) return {};
|
|
98
|
+
const b = base && typeof base === 'object' && !Array.isArray(base) ? base as Record<string, unknown> : {};
|
|
99
|
+
return { provider: { ...b, order, allow_fallbacks: false } };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** 도구 스키마에 Kimi sanitizer(`$ref` 단독 · 단일 items)를 씌울 모델인가 — moonshotai/* ⊕ deepseek/*. */
|
|
103
|
+
export function openRouterNeedsKimiToolSchema(wireModel: string): boolean {
|
|
104
|
+
return wireModel.startsWith('moonshotai/') || isOpenRouterDeepSeekWireModel(wireModel);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** 재전송용 `reasoning_details` 에서 «빈» 조각을 걷는다(text·summary·data 가 모두 비었으면 버림).
|
|
108
|
+
* 다 걷히면 `undefined` — 빈 배열·빈 문자열 placeholder 를 절대 싣지 않는다. */
|
|
109
|
+
export function nonEmptyReasoningDetails(
|
|
110
|
+
details: ReadonlyArray<Record<string, unknown>> | undefined,
|
|
111
|
+
): Array<Record<string, unknown>> | undefined {
|
|
112
|
+
if (!Array.isArray(details) || details.length === 0) return undefined;
|
|
113
|
+
const kept = details.filter((d) => ['text', 'summary', 'data'].some((k) => typeof d?.[k] === 'string' && (d[k] as string).length > 0));
|
|
114
|
+
return kept.length > 0 ? kept : undefined;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** 관측 `llm.openrouter deepseek-replay` 의 재료 — 보낼 wire 메시지에서 assistant 턴과 추론 재전송 수를 센다. */
|
|
118
|
+
export function summarizeDeepSeekReplay(wireMessages: ReadonlyArray<Record<string, unknown>>): {
|
|
119
|
+
assistantTurns: number; withReasoning: number; toolTurns: number; textTurnsWithReasoning: number;
|
|
120
|
+
} {
|
|
121
|
+
let assistantTurns = 0; let withReasoning = 0; let toolTurns = 0; let textTurnsWithReasoning = 0;
|
|
122
|
+
for (const m of wireMessages) {
|
|
123
|
+
if (m.role !== 'assistant') continue;
|
|
124
|
+
assistantTurns++;
|
|
125
|
+
const hasTools = Array.isArray(m.tool_calls) && m.tool_calls.length > 0;
|
|
126
|
+
if (hasTools) toolTurns++;
|
|
127
|
+
if (Array.isArray(m.reasoning_details) && m.reasoning_details.length > 0) {
|
|
128
|
+
withReasoning++;
|
|
129
|
+
if (!hasTools) textTurnsWithReasoning++;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return { assistantTurns, withReasoning, toolTurns, textTurnsWithReasoning };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** 요청 한 번의 DeepSeek 부가물 — 본문 `provider` 칸(상류 고정) ⊕ 관측 `llm.openrouter deepseek-replay` 한 줄.
|
|
136
|
+
* ⛔ DeepSeek 가 아니면 `{}` 이고 아무것도 남기지 않는다. */
|
|
137
|
+
export function openRouterDeepSeekRequestExtras(
|
|
138
|
+
wireModel: string,
|
|
139
|
+
wireMessages: ReadonlyArray<Record<string, unknown>>,
|
|
140
|
+
baseProvider: unknown,
|
|
141
|
+
explicitPreferences: unknown,
|
|
142
|
+
userPins?: unknown,
|
|
143
|
+
): { provider?: Record<string, unknown> } {
|
|
144
|
+
if (!isOpenRouterDeepSeekWireModel(wireModel)) return {};
|
|
145
|
+
const field = openRouterDeepSeekProviderField(wireModel, baseProvider, explicitPreferences, userPins);
|
|
146
|
+
debug.log('llm.openrouter', 'deepseek-replay', {
|
|
147
|
+
model: wireModel, ...summarizeDeepSeekReplay(wireMessages),
|
|
148
|
+
upstreamPin: (field.provider?.order as string[] | undefined) ?? null,
|
|
149
|
+
});
|
|
150
|
+
return field;
|
|
151
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// OR-DEEPSEEK-TUNE — OpenRouter 상류 고정 «설정 기본값»(데이터만 · 로직 없음).
|
|
2
|
+
//
|
|
3
|
+
// 키 = OpenRouter wire 모델 id(`openrouter/` 를 뗀 것) · 값 = 본문 `provider.order` 로 실을 상류 slug(⊕ allow_fallbacks:false).
|
|
4
|
+
// ⛔ 이 표는 코드가 아니라 «설정 기본값»이다 — 사용자 설정 `llm.openrouter.upstreamPins` 가 모델별로 덮는다
|
|
5
|
+
// (빈 배열 `[]` = 그 모델은 고정하지 않음 · OpenRouter 기본 라우팅). `llm.openrouter.providerPreferences` 에
|
|
6
|
+
// `order`·`only`·`allow_fallbacks` 중 하나라도 있으면 그것이 이기고 이 표는 쓰이지 않는다.
|
|
7
|
+
// ⛔ 표에 없는 모델은 고정하지 않는다.
|
|
8
|
+
//
|
|
9
|
+
// 📏 선정(2026-10-11 · OP 결정 ⓑ) — 공개 `GET /api/v1/models/deepseek/<slug>/endpoints`(인증 없음) 실측:
|
|
10
|
+
// 기준 = 데이터 학습 안 함 ⊕ max_completion_tokens ≥ 131072 ⊕ uptime_last_1d ≥ 99.
|
|
11
|
+
// ⚠️ 공개 endpoint 데이터엔 학습 정책 칸이 «없다» → 학습 여부는 우리 계정 Guardrails(학습 금지) 실측으로 갈랐다:
|
|
12
|
+
// 라우팅 퍼널에서 «Paid model training violation» 으로 걸러진 것은 `deepseek`(공식) 하나뿐이었고, 아래 고른 상류는
|
|
13
|
+
// 실호출 200 으로 통과를 확인했다.
|
|
14
|
+
// 동률(uptime 100 다수) → fp4 제외 · tool_choice=required 지원 · 입출력 단가 합이 가장 낮은 곳.
|
|
15
|
+
// ⊕ 4번째 기준(OP 2026-10-11) «2턴째 캐시 적중 > 0.5»(2턴 도구 교환 실호출) · 판촉 할인가 엔드포인트(baidu)는 제외.
|
|
16
|
+
// - deepseek-v4-pro-0813 → streamlake · out 384000 · uptime 1d 99.86 · $0.66 / $1.98 per MTok (cache read $0.022)
|
|
17
|
+
// 실측 2턴째 캐시: baidu/fp8 0(제외) → streamlake 0.94(선정) · alibaba 0.94(통과 · 차순위)
|
|
18
|
+
// - deepseek-v4.1-flash → deepinfra/fp8 · out 131072 · uptime 1d 100 · $0.14 / $0.42 per MTok (cache read $0.0042)
|
|
19
|
+
// 실측 2턴째 캐시 0.98
|
|
20
|
+
// ⚠️ endpoint 의 `supports_implicit_caching` 은 위 상류 모두 false 였다 — 캐시는 이 칸이 아니라 실호출로 가른다.
|
|
21
|
+
// 값이 늙는다 — 다시 재려면 위 endpoint 를 같은 기준으로 다시 정렬한다.
|
|
22
|
+
export const DEFAULT_OPENROUTER_UPSTREAM_PINS: Readonly<Record<string, readonly string[]>> = Object.freeze({
|
|
23
|
+
'deepseek/deepseek-v4-pro-0813': Object.freeze(['streamlake']),
|
|
24
|
+
'deepseek/deepseek-v4.1-flash': Object.freeze(['deepinfra/fp8']),
|
|
25
|
+
});
|