@remnic/core 9.69.66 → 9.69.67

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.
Files changed (201) hide show
  1. package/dist/access-admin-ops-surface.js +27 -26
  2. package/dist/access-audit.js +2 -2
  3. package/dist/access-authorization-probe.js +28 -27
  4. package/dist/access-boundary.js +27 -26
  5. package/dist/access-cli.js +78 -77
  6. package/dist/access-cli.js.map +1 -1
  7. package/dist/access-extraction-force-flush.js +27 -26
  8. package/dist/access-http-briefing.js +28 -27
  9. package/dist/access-http-query.js +29 -28
  10. package/dist/access-http.js +47 -46
  11. package/dist/access-identity-continuity-surface.js +27 -26
  12. package/dist/access-lcm-surface.js +27 -26
  13. package/dist/access-mcp.js +37 -36
  14. package/dist/access-namespace-preflight.js +27 -26
  15. package/dist/access-observe-write-surface.js +27 -26
  16. package/dist/access-operations-batch.js +29 -28
  17. package/dist/access-operations.js +36 -35
  18. package/dist/access-recall-concurrency.js +27 -26
  19. package/dist/access-recall-response.js +27 -26
  20. package/dist/access-recall-surface.js +27 -26
  21. package/dist/access-service.js +27 -26
  22. package/dist/access-surface-catalog.js +29 -28
  23. package/dist/access-surface-catalog.js.map +1 -1
  24. package/dist/active-recall.js +8 -8
  25. package/dist/adapters/index.js +4 -4
  26. package/dist/adapters/registry.js +2 -2
  27. package/dist/briefing.js +7 -7
  28. package/dist/causal-consolidation.js +8 -8
  29. package/dist/{chunk-CFCAFAJC.js → chunk-266NJ2YF.js} +2 -2
  30. package/dist/{chunk-LQ4OSM5V.js → chunk-2LT2GSTI.js} +6 -6
  31. package/dist/{chunk-YGJMMMPN.js → chunk-2VV3XLZB.js} +2 -2
  32. package/dist/{chunk-B2JE56NB.js → chunk-3R34HFBY.js} +2 -2
  33. package/dist/{chunk-MUGLJAZ3.js → chunk-4M375K73.js} +2 -2
  34. package/dist/{chunk-WZ33AIOP.js → chunk-5ID5RTHY.js} +2 -2
  35. package/dist/{chunk-WUUGE7QC.js → chunk-5TC6MQOW.js} +4 -4
  36. package/dist/{chunk-PSGRZFBH.js → chunk-A5IRUJMX.js} +11 -11
  37. package/dist/{chunk-X2NFFBTO.js → chunk-A7GQBJP5.js} +4 -4
  38. package/dist/{chunk-OCEIHKH5.js → chunk-ADZLUBNE.js} +3 -3
  39. package/dist/{chunk-ITLFUILH.js → chunk-AJEUESNJ.js} +2 -2
  40. package/dist/{chunk-D433RXFJ.js → chunk-AYDU5MJC.js} +2 -2
  41. package/dist/{chunk-II4TIQCU.js → chunk-B2FMRNHA.js} +2 -2
  42. package/dist/{chunk-I4IKTNZP.js → chunk-B6RTKSOT.js} +3 -3
  43. package/dist/{chunk-C2W6JKQQ.js → chunk-BGBW4H7C.js} +2 -2
  44. package/dist/{chunk-5C765XYU.js → chunk-BSCR5TEN.js} +2 -2
  45. package/dist/{chunk-CZM4MHZF.js → chunk-C7K7YV65.js} +31 -31
  46. package/dist/{chunk-7L747CFR.js → chunk-CMAGVPS2.js} +2 -2
  47. package/dist/{chunk-U6GKPSZH.js → chunk-D5F2Z6WO.js} +2 -2
  48. package/dist/{chunk-ZX5N5D6M.js → chunk-DAOMWGO2.js} +4 -4
  49. package/dist/{chunk-L4HT5QZ5.js → chunk-DDNML3YE.js} +2 -2
  50. package/dist/{chunk-6YTL3JYX.js → chunk-DQEM4LDV.js} +2 -2
  51. package/dist/{chunk-O7QF3TCV.js → chunk-DUWNHPZ2.js} +25 -25
  52. package/dist/{chunk-XJNSOI23.js → chunk-FN6E373Q.js} +2 -2
  53. package/dist/{chunk-NYN4ZMPL.js → chunk-FZ4BU3WD.js} +2 -2
  54. package/dist/{chunk-2PKGJPQL.js → chunk-G3QJVHFG.js} +4 -4
  55. package/dist/{chunk-LI4IWBLN.js → chunk-GNC5X3J7.js} +5 -5
  56. package/dist/{chunk-GZLSIPYU.js → chunk-GUWH5SOO.js} +2 -2
  57. package/dist/{chunk-FO5NDQZH.js → chunk-HRQWSXNB.js} +3 -3
  58. package/dist/{chunk-62JTOLEX.js → chunk-I53NAHZ4.js} +14 -65
  59. package/dist/chunk-I53NAHZ4.js.map +1 -0
  60. package/dist/{chunk-AQ6IBVFQ.js → chunk-JDBZSRUA.js} +2 -2
  61. package/dist/{chunk-E7SKAUEW.js → chunk-JX2NWPQ4.js} +8 -8
  62. package/dist/{chunk-EK4MOTHM.js → chunk-MQTCNXTG.js} +4 -4
  63. package/dist/{chunk-2ZVSQPAA.js → chunk-MZQ2MBET.js} +19 -19
  64. package/dist/{chunk-3S4R2HA5.js → chunk-NEARGPN7.js} +2 -2
  65. package/dist/{chunk-ZSXSMVW6.js → chunk-NPA73KGP.js} +2 -2
  66. package/dist/{chunk-3NG5OOCX.js → chunk-NZUHZVHF.js} +2 -2
  67. package/dist/{chunk-5WXJE5TV.js → chunk-OAOBL6OY.js} +2 -2
  68. package/dist/{chunk-TO3G56GM.js → chunk-OVO545UE.js} +2 -2
  69. package/dist/{chunk-QMWKENNK.js → chunk-Q4AUIFUA.js} +4 -4
  70. package/dist/{chunk-Y3AFTYK4.js → chunk-RDWVTUXZ.js} +2 -2
  71. package/dist/{chunk-OBD77TYC.js → chunk-RG7ZWG3M.js} +2 -2
  72. package/dist/{chunk-DT33WNG2.js → chunk-S4W66FQ7.js} +3 -3
  73. package/dist/{chunk-JLU7WK22.js → chunk-SUI5JQVE.js} +2 -2
  74. package/dist/{chunk-YIDBKTZJ.js → chunk-SYBHLTFW.js} +2 -2
  75. package/dist/{chunk-IOUQUXHO.js → chunk-TRLPF7ZP.js} +2 -2
  76. package/dist/chunk-U4LUIE6Y.js +76 -0
  77. package/dist/chunk-U4LUIE6Y.js.map +1 -0
  78. package/dist/{chunk-ZPPWW576.js → chunk-UBCVHKZQ.js} +2 -2
  79. package/dist/{chunk-IJQEVNEF.js → chunk-VQJ7UAKA.js} +1 -1
  80. package/dist/{chunk-M3TMVHQ2.js → chunk-VVKLAB3Y.js} +2 -2
  81. package/dist/{chunk-755VRFBS.js → chunk-WJPRWNZN.js} +2 -2
  82. package/dist/{chunk-IULYVB5X.js → chunk-WTD4JHFP.js} +5 -5
  83. package/dist/{chunk-5AABWM72.js → chunk-WXPIEWQW.js} +3 -3
  84. package/dist/{chunk-XGLBVYEA.js → chunk-XY25CPAO.js} +8 -8
  85. package/dist/{chunk-4RWPQZYD.js → chunk-YED2GFH6.js} +2 -2
  86. package/dist/{chunk-XDIFADVN.js → chunk-YZH4O4NA.js} +2 -2
  87. package/dist/{chunk-BE4GMH45.js → chunk-ZDTG7ALZ.js} +2 -2
  88. package/dist/{chunk-DDY7LJMP.js → chunk-ZMU7UK2Q.js} +2 -2
  89. package/dist/cli.js +62 -61
  90. package/dist/coding/export-okf-codegraph.js +6 -6
  91. package/dist/compounding/engine.js +7 -7
  92. package/dist/config.js +8 -8
  93. package/dist/connectors/codex-materialize-runner.js +7 -7
  94. package/dist/connectors/index.js +7 -7
  95. package/dist/convergence-refresh.js +9 -9
  96. package/dist/corpus-watermark.js +9 -9
  97. package/dist/deep-recall.js +2 -2
  98. package/dist/entity-retrieval.js +7 -7
  99. package/dist/external-wiki-access.js +28 -27
  100. package/dist/extraction.js +10 -9
  101. package/dist/harmonic-retrieval.js +1 -1
  102. package/dist/index.js +84 -83
  103. package/dist/lcm/engine.js +2 -2
  104. package/dist/lcm/index.js +4 -4
  105. package/dist/local-llm-servers.d.ts +23 -0
  106. package/dist/local-llm-servers.d.ts.map +1 -0
  107. package/dist/local-llm-servers.js +10 -0
  108. package/dist/local-llm-servers.js.map +1 -0
  109. package/dist/local-llm.d.ts +8 -7
  110. package/dist/local-llm.d.ts.map +1 -1
  111. package/dist/local-llm.js +2 -1
  112. package/dist/location/index.js +9 -9
  113. package/dist/maintenance/memory-governance.js +7 -7
  114. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +7 -7
  115. package/dist/maintenance/rebuild-memory-projection.js +8 -8
  116. package/dist/memory-browse-operations.js +28 -27
  117. package/dist/namespaces/migrate.js +8 -8
  118. package/dist/namespaces/search.js +4 -4
  119. package/dist/namespaces/storage.js +7 -7
  120. package/dist/operator-doctor-corpus.js +10 -10
  121. package/dist/operator-toolkit.js +17 -17
  122. package/dist/orchestration/maintenance.js +17 -16
  123. package/dist/orchestrator.js +78 -77
  124. package/dist/recall-navigation-operations.js +28 -27
  125. package/dist/recall-navigation.js +27 -26
  126. package/dist/resume-bundles.js +9 -9
  127. package/dist/search/factory.js +3 -3
  128. package/dist/search/index.js +7 -7
  129. package/dist/semantic-consolidation.js +8 -8
  130. package/dist/semantic-rule-promotion.js +7 -7
  131. package/dist/semantic-rule-verifier.js +7 -7
  132. package/dist/source-agent-qualifier.js +7 -7
  133. package/dist/standup/build.js +7 -7
  134. package/dist/storage.js +6 -6
  135. package/dist/summarizer.js +3 -2
  136. package/dist/support-passport/index.js +30 -29
  137. package/dist/transfer/export-okf.js +7 -7
  138. package/dist/verified-recall.js +7 -7
  139. package/dist/who-knows-cli.js +8 -8
  140. package/dist/who-knows.js +7 -7
  141. package/package.json +2 -2
  142. package/src/local-llm-probe-litellm.test.ts +116 -0
  143. package/src/local-llm-servers.ts +104 -0
  144. package/src/local-llm.ts +25 -85
  145. package/dist/chunk-62JTOLEX.js.map +0 -1
  146. /package/dist/{chunk-CFCAFAJC.js.map → chunk-266NJ2YF.js.map} +0 -0
  147. /package/dist/{chunk-LQ4OSM5V.js.map → chunk-2LT2GSTI.js.map} +0 -0
  148. /package/dist/{chunk-YGJMMMPN.js.map → chunk-2VV3XLZB.js.map} +0 -0
  149. /package/dist/{chunk-B2JE56NB.js.map → chunk-3R34HFBY.js.map} +0 -0
  150. /package/dist/{chunk-MUGLJAZ3.js.map → chunk-4M375K73.js.map} +0 -0
  151. /package/dist/{chunk-WZ33AIOP.js.map → chunk-5ID5RTHY.js.map} +0 -0
  152. /package/dist/{chunk-WUUGE7QC.js.map → chunk-5TC6MQOW.js.map} +0 -0
  153. /package/dist/{chunk-PSGRZFBH.js.map → chunk-A5IRUJMX.js.map} +0 -0
  154. /package/dist/{chunk-X2NFFBTO.js.map → chunk-A7GQBJP5.js.map} +0 -0
  155. /package/dist/{chunk-OCEIHKH5.js.map → chunk-ADZLUBNE.js.map} +0 -0
  156. /package/dist/{chunk-ITLFUILH.js.map → chunk-AJEUESNJ.js.map} +0 -0
  157. /package/dist/{chunk-D433RXFJ.js.map → chunk-AYDU5MJC.js.map} +0 -0
  158. /package/dist/{chunk-II4TIQCU.js.map → chunk-B2FMRNHA.js.map} +0 -0
  159. /package/dist/{chunk-I4IKTNZP.js.map → chunk-B6RTKSOT.js.map} +0 -0
  160. /package/dist/{chunk-C2W6JKQQ.js.map → chunk-BGBW4H7C.js.map} +0 -0
  161. /package/dist/{chunk-5C765XYU.js.map → chunk-BSCR5TEN.js.map} +0 -0
  162. /package/dist/{chunk-CZM4MHZF.js.map → chunk-C7K7YV65.js.map} +0 -0
  163. /package/dist/{chunk-7L747CFR.js.map → chunk-CMAGVPS2.js.map} +0 -0
  164. /package/dist/{chunk-U6GKPSZH.js.map → chunk-D5F2Z6WO.js.map} +0 -0
  165. /package/dist/{chunk-ZX5N5D6M.js.map → chunk-DAOMWGO2.js.map} +0 -0
  166. /package/dist/{chunk-L4HT5QZ5.js.map → chunk-DDNML3YE.js.map} +0 -0
  167. /package/dist/{chunk-6YTL3JYX.js.map → chunk-DQEM4LDV.js.map} +0 -0
  168. /package/dist/{chunk-O7QF3TCV.js.map → chunk-DUWNHPZ2.js.map} +0 -0
  169. /package/dist/{chunk-XJNSOI23.js.map → chunk-FN6E373Q.js.map} +0 -0
  170. /package/dist/{chunk-NYN4ZMPL.js.map → chunk-FZ4BU3WD.js.map} +0 -0
  171. /package/dist/{chunk-2PKGJPQL.js.map → chunk-G3QJVHFG.js.map} +0 -0
  172. /package/dist/{chunk-LI4IWBLN.js.map → chunk-GNC5X3J7.js.map} +0 -0
  173. /package/dist/{chunk-GZLSIPYU.js.map → chunk-GUWH5SOO.js.map} +0 -0
  174. /package/dist/{chunk-FO5NDQZH.js.map → chunk-HRQWSXNB.js.map} +0 -0
  175. /package/dist/{chunk-AQ6IBVFQ.js.map → chunk-JDBZSRUA.js.map} +0 -0
  176. /package/dist/{chunk-E7SKAUEW.js.map → chunk-JX2NWPQ4.js.map} +0 -0
  177. /package/dist/{chunk-EK4MOTHM.js.map → chunk-MQTCNXTG.js.map} +0 -0
  178. /package/dist/{chunk-2ZVSQPAA.js.map → chunk-MZQ2MBET.js.map} +0 -0
  179. /package/dist/{chunk-3S4R2HA5.js.map → chunk-NEARGPN7.js.map} +0 -0
  180. /package/dist/{chunk-ZSXSMVW6.js.map → chunk-NPA73KGP.js.map} +0 -0
  181. /package/dist/{chunk-3NG5OOCX.js.map → chunk-NZUHZVHF.js.map} +0 -0
  182. /package/dist/{chunk-5WXJE5TV.js.map → chunk-OAOBL6OY.js.map} +0 -0
  183. /package/dist/{chunk-TO3G56GM.js.map → chunk-OVO545UE.js.map} +0 -0
  184. /package/dist/{chunk-QMWKENNK.js.map → chunk-Q4AUIFUA.js.map} +0 -0
  185. /package/dist/{chunk-Y3AFTYK4.js.map → chunk-RDWVTUXZ.js.map} +0 -0
  186. /package/dist/{chunk-OBD77TYC.js.map → chunk-RG7ZWG3M.js.map} +0 -0
  187. /package/dist/{chunk-DT33WNG2.js.map → chunk-S4W66FQ7.js.map} +0 -0
  188. /package/dist/{chunk-JLU7WK22.js.map → chunk-SUI5JQVE.js.map} +0 -0
  189. /package/dist/{chunk-YIDBKTZJ.js.map → chunk-SYBHLTFW.js.map} +0 -0
  190. /package/dist/{chunk-IOUQUXHO.js.map → chunk-TRLPF7ZP.js.map} +0 -0
  191. /package/dist/{chunk-ZPPWW576.js.map → chunk-UBCVHKZQ.js.map} +0 -0
  192. /package/dist/{chunk-IJQEVNEF.js.map → chunk-VQJ7UAKA.js.map} +0 -0
  193. /package/dist/{chunk-M3TMVHQ2.js.map → chunk-VVKLAB3Y.js.map} +0 -0
  194. /package/dist/{chunk-755VRFBS.js.map → chunk-WJPRWNZN.js.map} +0 -0
  195. /package/dist/{chunk-IULYVB5X.js.map → chunk-WTD4JHFP.js.map} +0 -0
  196. /package/dist/{chunk-5AABWM72.js.map → chunk-WXPIEWQW.js.map} +0 -0
  197. /package/dist/{chunk-XGLBVYEA.js.map → chunk-XY25CPAO.js.map} +0 -0
  198. /package/dist/{chunk-4RWPQZYD.js.map → chunk-YED2GFH6.js.map} +0 -0
  199. /package/dist/{chunk-XDIFADVN.js.map → chunk-YZH4O4NA.js.map} +0 -0
  200. /package/dist/{chunk-BE4GMH45.js.map → chunk-ZDTG7ALZ.js.map} +0 -0
  201. /package/dist/{chunk-DDY7LJMP.js.map → chunk-ZMU7UK2Q.js.map} +0 -0
@@ -4,33 +4,33 @@ import {
4
4
  exportOkfBundle,
5
5
  firstHeading,
6
6
  parseIncludeStatus
7
- } from "../chunk-WZ33AIOP.js";
7
+ } from "../chunk-5ID5RTHY.js";
8
8
  import {
9
9
  OKF_EXPORT_VERSION
10
10
  } from "../chunk-UJX4I26O.js";
11
11
  import "../chunk-D24OXEPB.js";
12
12
  import "../chunk-3UXOZBHV.js";
13
- import "../chunk-LI4IWBLN.js";
13
+ import "../chunk-GNC5X3J7.js";
14
14
  import "../chunk-46WM6JX2.js";
15
15
  import "../chunk-UHVXE24Y.js";
16
16
  import "../chunk-D5F7TKMH.js";
17
- import "../chunk-C2W6JKQQ.js";
18
- import "../chunk-EK4MOTHM.js";
17
+ import "../chunk-BGBW4H7C.js";
18
+ import "../chunk-MQTCNXTG.js";
19
+ import "../chunk-T3FMRLWQ.js";
19
20
  import "../chunk-7VO6E5UD.js";
20
21
  import "../chunk-Z4TXB4K7.js";
21
22
  import "../chunk-S7LWX2PQ.js";
22
23
  import "../chunk-T2YX56QI.js";
23
- import "../chunk-CYEPCZN5.js";
24
- import "../chunk-T3FMRLWQ.js";
25
24
  import "../chunk-4O6WRBGE.js";
26
25
  import "../chunk-GUMZC2BO.js";
26
+ import "../chunk-CYEPCZN5.js";
27
27
  import "../chunk-TFA6HPOA.js";
28
28
  import "../chunk-F4TWWUMP.js";
29
29
  import "../chunk-72A4L5JJ.js";
30
30
  import "../chunk-A7Q43EUZ.js";
31
31
  import "../chunk-S2V7RUCL.js";
32
- import "../chunk-MRPOZBJC.js";
33
32
  import "../chunk-S2HLHAZ4.js";
33
+ import "../chunk-MRPOZBJC.js";
34
34
  import "../chunk-DM2T26WE.js";
35
35
  import "../chunk-LDXUBPMO.js";
36
36
  import "../chunk-FF6N7BXC.js";
@@ -1,29 +1,29 @@
1
1
  import {
2
2
  compareVerifiedEpisodeResults,
3
3
  searchVerifiedEpisodes
4
- } from "./chunk-L4HT5QZ5.js";
4
+ } from "./chunk-DDNML3YE.js";
5
5
  import "./chunk-B7RWBZXW.js";
6
- import "./chunk-LI4IWBLN.js";
6
+ import "./chunk-GNC5X3J7.js";
7
7
  import "./chunk-46WM6JX2.js";
8
8
  import "./chunk-UHVXE24Y.js";
9
9
  import "./chunk-D5F7TKMH.js";
10
- import "./chunk-C2W6JKQQ.js";
11
- import "./chunk-EK4MOTHM.js";
10
+ import "./chunk-BGBW4H7C.js";
11
+ import "./chunk-MQTCNXTG.js";
12
+ import "./chunk-T3FMRLWQ.js";
12
13
  import "./chunk-7VO6E5UD.js";
13
14
  import "./chunk-Z4TXB4K7.js";
14
15
  import "./chunk-S7LWX2PQ.js";
15
16
  import "./chunk-T2YX56QI.js";
16
- import "./chunk-CYEPCZN5.js";
17
- import "./chunk-T3FMRLWQ.js";
18
17
  import "./chunk-4O6WRBGE.js";
19
18
  import "./chunk-GUMZC2BO.js";
19
+ import "./chunk-CYEPCZN5.js";
20
20
  import "./chunk-TFA6HPOA.js";
21
21
  import "./chunk-F4TWWUMP.js";
22
22
  import "./chunk-72A4L5JJ.js";
23
23
  import "./chunk-A7Q43EUZ.js";
24
24
  import "./chunk-S2V7RUCL.js";
25
- import "./chunk-MRPOZBJC.js";
26
25
  import "./chunk-S2HLHAZ4.js";
26
+ import "./chunk-MRPOZBJC.js";
27
27
  import "./chunk-DM2T26WE.js";
28
28
  import "./chunk-LDXUBPMO.js";
29
29
  import "./chunk-FF6N7BXC.js";
@@ -4,29 +4,29 @@ import {
4
4
  renderWhoKnows,
5
5
  renderWhoKnowsJson,
6
6
  renderWhoKnowsText
7
- } from "./chunk-OBD77TYC.js";
8
- import "./chunk-7L747CFR.js";
9
- import "./chunk-LI4IWBLN.js";
7
+ } from "./chunk-RG7ZWG3M.js";
8
+ import "./chunk-CMAGVPS2.js";
9
+ import "./chunk-GNC5X3J7.js";
10
10
  import "./chunk-46WM6JX2.js";
11
11
  import "./chunk-UHVXE24Y.js";
12
12
  import "./chunk-D5F7TKMH.js";
13
- import "./chunk-C2W6JKQQ.js";
14
- import "./chunk-EK4MOTHM.js";
13
+ import "./chunk-BGBW4H7C.js";
14
+ import "./chunk-MQTCNXTG.js";
15
+ import "./chunk-T3FMRLWQ.js";
15
16
  import "./chunk-7VO6E5UD.js";
16
17
  import "./chunk-Z4TXB4K7.js";
17
18
  import "./chunk-S7LWX2PQ.js";
18
19
  import "./chunk-T2YX56QI.js";
19
- import "./chunk-CYEPCZN5.js";
20
- import "./chunk-T3FMRLWQ.js";
21
20
  import "./chunk-4O6WRBGE.js";
22
21
  import "./chunk-GUMZC2BO.js";
22
+ import "./chunk-CYEPCZN5.js";
23
23
  import "./chunk-TFA6HPOA.js";
24
24
  import "./chunk-F4TWWUMP.js";
25
25
  import "./chunk-72A4L5JJ.js";
26
26
  import "./chunk-A7Q43EUZ.js";
27
27
  import "./chunk-S2V7RUCL.js";
28
- import "./chunk-MRPOZBJC.js";
29
28
  import "./chunk-S2HLHAZ4.js";
29
+ import "./chunk-MRPOZBJC.js";
30
30
  import "./chunk-DM2T26WE.js";
31
31
  import "./chunk-LDXUBPMO.js";
32
32
  import "./chunk-FF6N7BXC.js";
package/dist/who-knows.js CHANGED
@@ -9,28 +9,28 @@ import {
9
9
  loadWhoKnowsEntities,
10
10
  tokenizeTopic,
11
11
  validateWhoKnowsInput
12
- } from "./chunk-7L747CFR.js";
13
- import "./chunk-LI4IWBLN.js";
12
+ } from "./chunk-CMAGVPS2.js";
13
+ import "./chunk-GNC5X3J7.js";
14
14
  import "./chunk-46WM6JX2.js";
15
15
  import "./chunk-UHVXE24Y.js";
16
16
  import "./chunk-D5F7TKMH.js";
17
- import "./chunk-C2W6JKQQ.js";
18
- import "./chunk-EK4MOTHM.js";
17
+ import "./chunk-BGBW4H7C.js";
18
+ import "./chunk-MQTCNXTG.js";
19
+ import "./chunk-T3FMRLWQ.js";
19
20
  import "./chunk-7VO6E5UD.js";
20
21
  import "./chunk-Z4TXB4K7.js";
21
22
  import "./chunk-S7LWX2PQ.js";
22
23
  import "./chunk-T2YX56QI.js";
23
- import "./chunk-CYEPCZN5.js";
24
- import "./chunk-T3FMRLWQ.js";
25
24
  import "./chunk-4O6WRBGE.js";
26
25
  import "./chunk-GUMZC2BO.js";
26
+ import "./chunk-CYEPCZN5.js";
27
27
  import "./chunk-TFA6HPOA.js";
28
28
  import "./chunk-F4TWWUMP.js";
29
29
  import "./chunk-72A4L5JJ.js";
30
30
  import "./chunk-A7Q43EUZ.js";
31
31
  import "./chunk-S2V7RUCL.js";
32
- import "./chunk-MRPOZBJC.js";
33
32
  import "./chunk-S2HLHAZ4.js";
33
+ import "./chunk-MRPOZBJC.js";
34
34
  import "./chunk-DM2T26WE.js";
35
35
  import "./chunk-LDXUBPMO.js";
36
36
  import "./chunk-FF6N7BXC.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "9.69.66",
3
+ "version": "9.69.67",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -3317,7 +3317,7 @@
3317
3317
  "core"
3318
3318
  ],
3319
3319
  "peerDependencies": {
3320
- "@remnic/coding-graph": "^9.69.66"
3320
+ "@remnic/coding-graph": "^9.69.67"
3321
3321
  },
3322
3322
  "peerDependenciesMeta": {
3323
3323
  "@remnic/coding-graph": {
@@ -0,0 +1,116 @@
1
+ import assert from "node:assert/strict";
2
+ import http from "node:http";
3
+ import type { AddressInfo } from "node:net";
4
+ import test from "node:test";
5
+
6
+ import { LocalLlmClient } from "./local-llm.js";
7
+ import { orderedLocalServers } from "./local-llm-servers.js";
8
+ import type { PluginConfig } from "./types.js";
9
+
10
+ /**
11
+ * A LiteLLM proxy answers `GET /` with the JSON string "LiteLLM: RUNNING" and
12
+ * runs a live completion against every deployment in its pool on `GET /health`.
13
+ * The availability probe must classify LiteLLM from `/` and never reach
14
+ * `/health`; before this test the once-a-minute probe was the largest load
15
+ * source on the pool behind the proxy.
16
+ */
17
+
18
+ function createConfig(localLlmUrl: string): PluginConfig {
19
+ return {
20
+ localLlmEnabled: true,
21
+ localLlmModel: "test-local-model",
22
+ localLlmUrl,
23
+ localLlmTimeoutMs: 1_000,
24
+ localLlmRetry5xxCount: 0,
25
+ localLlmRetryBackoffMs: 1,
26
+ localLlmHeaders: {},
27
+ localLlmApiKey: undefined,
28
+ localLlmAuthHeader: false,
29
+ localLlm400TripThreshold: 3,
30
+ localLlm400CooldownMs: 60_000,
31
+ debug: false,
32
+ localLlmReasoningEffort: "none",
33
+ slowLogEnabled: false,
34
+ slowLogThresholdMs: 1_000,
35
+ } as unknown as PluginConfig;
36
+ }
37
+
38
+ async function startServer(
39
+ handle: (path: string, res: http.ServerResponse) => void,
40
+ ): Promise<{ url: string; paths: string[]; close(): Promise<void> }> {
41
+ const paths: string[] = [];
42
+ const server = http.createServer((req, res) => {
43
+ const path = req.url ?? "";
44
+ paths.push(path);
45
+ handle(path, res);
46
+ });
47
+ await new Promise<void>((resolve) => server.listen(0, "127.0.0.1", resolve));
48
+ const { port } = server.address() as AddressInfo;
49
+ return {
50
+ url: `http://127.0.0.1:${port}/v1`,
51
+ paths,
52
+ close: () => new Promise<void>((resolve) => server.close(() => resolve())),
53
+ };
54
+ }
55
+
56
+ function json(res: http.ServerResponse, body: unknown): void {
57
+ res.writeHead(200, { "content-type": "application/json" });
58
+ res.end(JSON.stringify(body));
59
+ }
60
+
61
+ function startLiteLlmShapedServer() {
62
+ return startServer((path, res) => {
63
+ if (path === "/") return json(res, "LiteLLM: RUNNING");
64
+ if (path === "/v1/models") return json(res, { data: [{ id: "test-local-model" }] });
65
+ json(res, { healthy_endpoints: [], unhealthy_endpoints: [] });
66
+ });
67
+ }
68
+
69
+ test("a LiteLLM proxy is detected from GET / and /health is never probed", async () => {
70
+ const server = await startLiteLlmShapedServer();
71
+ try {
72
+ const client = new LocalLlmClient(createConfig(server.url));
73
+ assert.equal(await client.checkAvailability(), true);
74
+ assert.equal(client.getDetectedType(), "litellm");
75
+ assert.ok(!server.paths.includes("/health"), `probe hit /health: ${server.paths.join(", ")}`);
76
+ assert.equal(server.paths.filter((p) => p === "/").length, 1, "GET / must be fetched once per pass");
77
+ } finally {
78
+ await server.close();
79
+ }
80
+ });
81
+
82
+ test("LiteLLM is probed before any /health probe on every port; other orders are unchanged", () => {
83
+ for (const port of [8080, 8000, 11434, 1234, 4000, null]) {
84
+ const url = port === null ? "http://127.0.0.1/v1" : `http://127.0.0.1:${port}/v1`;
85
+ const order = orderedLocalServers(url);
86
+ const types = order.map((s) => s.type);
87
+ const litellmAt = types.indexOf("litellm");
88
+ const firstHealth = order.findIndex((s) => s.healthEndpoint === "/health");
89
+ assert.ok(litellmAt !== -1 && litellmAt < firstHealth, `${url}: ${types.join(" > ")}`);
90
+ }
91
+ // Port-matched shapes with harmless probes keep the lead they had before.
92
+ assert.equal(orderedLocalServers("http://127.0.0.1:1234/v1")[0]?.type, "lmstudio");
93
+ assert.equal(orderedLocalServers("http://127.0.0.1:11434/v1")[0]?.type, "ollama");
94
+ // LiteLLM displaces the port-matched llama.cpp / vLLM /health probes.
95
+ assert.deepEqual(orderedLocalServers("http://127.0.0.1:8080/v1").map((s) => s.type).slice(0, 3), ["litellm", "llamacpp", "mlx"]);
96
+ assert.deepEqual(orderedLocalServers("http://127.0.0.1:8000/v1").map((s) => s.type).slice(0, 2), ["litellm", "vllm"]);
97
+ });
98
+
99
+ test("a root response is fetched once even when a later detector matches it", async () => {
100
+ const server = await startServer((path, res) => {
101
+ if (path === "/") {
102
+ res.writeHead(200, { "content-type": "text/plain" });
103
+ res.end("Ollama is running");
104
+ return;
105
+ }
106
+ json(res, {});
107
+ });
108
+ try {
109
+ const client = new LocalLlmClient(createConfig(server.url));
110
+ assert.equal(await client.checkAvailability(), true);
111
+ assert.equal(client.getDetectedType(), "ollama");
112
+ assert.equal(server.paths.filter((p) => p === "/").length, 1, `paths: ${server.paths.join(", ")}`);
113
+ } finally {
114
+ await server.close();
115
+ }
116
+ });
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Server shapes the local-LLM availability probe can recognise, and the order
3
+ * in which they are tried for a configured base URL. Split from local-llm.ts
4
+ * (file-size ratchet) — no runtime dependency on the client.
5
+ */
6
+
7
+ export type LocalLlmType = "litellm" | "lmstudio" | "ollama" | "mlx" | "vllm" | "llamacpp" | "generic";
8
+
9
+ export interface LocalServerConfig {
10
+ type: LocalLlmType;
11
+ defaultPort: number;
12
+ healthEndpoint: string;
13
+ modelsEndpoint: string;
14
+ detectFn: (response: unknown) => boolean;
15
+ }
16
+
17
+ export function isObjectRecord(value: unknown): value is Record<string, unknown> {
18
+ return typeof value === "object" && value !== null;
19
+ }
20
+
21
+ function explicitPortFromUrl(s: string): number | null {
22
+ try {
23
+ const parsed = new URL(s);
24
+ if (!parsed.port) return null;
25
+ const port = Number(parsed.port);
26
+ return Number.isInteger(port) ? port : null;
27
+ } catch {
28
+ return null;
29
+ }
30
+ }
31
+
32
+ // LiteLLM must be recognised before the llama.cpp / vLLM probes: on a LiteLLM
33
+ // proxy `GET /health` runs a live completion against EVERY deployment in its
34
+ // pool, so a once-a-minute 2 s probe turns into a permanent load generator on
35
+ // the backends (4,600 probe completions in 12 h observed). `GET /` is
36
+ // auth-gated on LiteLLM and answers the JSON string "LiteLLM: RUNNING".
37
+ // Not part of LOCAL_SERVERS: `orderedLocalServers` positions it explicitly.
38
+ const LITELLM_SERVER: LocalServerConfig = {
39
+ type: "litellm",
40
+ defaultPort: 4000,
41
+ healthEndpoint: "/",
42
+ modelsEndpoint: "/v1/models",
43
+ detectFn: (resp) => typeof resp === "string" && resp.includes("LiteLLM"),
44
+ };
45
+
46
+ const LOCAL_SERVERS: LocalServerConfig[] = [
47
+ {
48
+ type: "ollama",
49
+ defaultPort: 11434,
50
+ healthEndpoint: "/",
51
+ modelsEndpoint: "/api/tags",
52
+ detectFn: (resp) => typeof resp === "string" && resp.includes("Ollama"),
53
+ },
54
+ {
55
+ type: "llamacpp",
56
+ defaultPort: 8080,
57
+ healthEndpoint: "/health",
58
+ modelsEndpoint: "/v1/models",
59
+ detectFn: (resp) => isObjectRecord(resp) && resp.status === "ok",
60
+ },
61
+ {
62
+ type: "mlx",
63
+ defaultPort: 8080,
64
+ healthEndpoint: "/v1/models",
65
+ modelsEndpoint: "/v1/models",
66
+ detectFn: (resp) => isObjectRecord(resp) && Array.isArray(resp.data),
67
+ },
68
+ {
69
+ type: "lmstudio",
70
+ defaultPort: 1234,
71
+ healthEndpoint: "/v1/models",
72
+ modelsEndpoint: "/v1/models",
73
+ detectFn: (resp) => isObjectRecord(resp) && Array.isArray(resp.data),
74
+ },
75
+ {
76
+ type: "vllm",
77
+ defaultPort: 8000,
78
+ healthEndpoint: "/health",
79
+ modelsEndpoint: "/v1/models",
80
+ detectFn: (resp) => resp === "" || (isObjectRecord(resp) && !("status" in resp)),
81
+ },
82
+ ];
83
+
84
+ /**
85
+ * Probe order for a configured base URL. Entries whose default port matches
86
+ * the URL's explicit port go first, in the same order as before; the LiteLLM
87
+ * entry is placed immediately ahead of the first entry that would probe
88
+ * `GET /health`, so that request never reaches a LiteLLM proxy on any port.
89
+ * LM Studio / Ollama / MLX probes are harmless on LiteLLM and keep their spot.
90
+ */
91
+ export function orderedLocalServers(configuredBaseUrl: string): LocalServerConfig[] {
92
+ const configuredPort = explicitPortFromUrl(configuredBaseUrl);
93
+ const matching = configuredPort === null
94
+ ? []
95
+ : LOCAL_SERVERS.filter((serverConfig) => serverConfig.defaultPort === configuredPort);
96
+ const matchingTypes = new Set(matching.map((serverConfig) => serverConfig.type));
97
+ const ordered = [
98
+ ...matching,
99
+ ...LOCAL_SERVERS.filter((serverConfig) => !matchingTypes.has(serverConfig.type)),
100
+ ];
101
+ const firstHealthProbe = ordered.findIndex((serverConfig) => serverConfig.healthEndpoint === "/health");
102
+ ordered.splice(firstHealthProbe === -1 ? ordered.length : firstHealthProbe, 0, LITELLM_SERVER);
103
+ return ordered;
104
+ }
package/src/local-llm.ts CHANGED
@@ -22,6 +22,13 @@ import {
22
22
  type LocalLlmChatCompletionOptions,
23
23
  type LocalLlmChatCompletionResult,
24
24
  } from "./local-llm-helpers.js";
25
+ import {
26
+ isObjectRecord,
27
+ orderedLocalServers,
28
+ type LocalLlmType,
29
+ } from "./local-llm-servers.js";
30
+
31
+ export type { LocalLlmType } from "./local-llm-servers.js";
25
32
 
26
33
  /** Trim trailing slash characters without backtracking regex. */
27
34
  function trimTrailingSlashes(s: string): string {
@@ -34,21 +41,6 @@ function stripTrailingV1Path(s: string): string {
34
41
  return s.endsWith("/v1") ? s.slice(0, -3) : s;
35
42
  }
36
43
 
37
- function explicitPortFromUrl(s: string): number | null {
38
- try {
39
- const parsed = new URL(s);
40
- if (!parsed.port) return null;
41
- const port = Number(parsed.port);
42
- return Number.isInteger(port) ? port : null;
43
- } catch {
44
- return null;
45
- }
46
- }
47
-
48
- function isObjectRecord(value: unknown): value is Record<string, unknown> {
49
- return typeof value === "object" && value !== null;
50
- }
51
-
52
44
  function isLlamaCppPropsResponse(value: unknown): boolean {
53
45
  return (
54
46
  isObjectRecord(value) &&
@@ -118,15 +110,6 @@ function isLmStudioNativeModelsResponse(value: unknown): boolean {
118
110
  return isLmStudioApiV1ModelsResponse(value) || isLmStudioApiV0ModelsResponse(value);
119
111
  }
120
112
 
121
- /**
122
- * Local LLM client for OpenAI-compatible endpoints (LM Studio, Ollama, MLX, etc.)
123
- *
124
- * Based on openclaw-tactician's provider detection patterns for consistency.
125
- * Provides privacy-preserving, cost-effective LLM operations with
126
- * graceful fallback to cloud providers when local LLM is unavailable.
127
- */
128
- export type LocalLlmType = "lmstudio" | "ollama" | "mlx" | "vllm" | "llamacpp" | "generic";
129
-
130
113
  /**
131
114
  * Backends known to honor `chat_template_kwargs: { enable_thinking: false }`
132
115
  * on OpenAI-compatible `/v1/chat/completions`. LM Studio, vLLM, and
@@ -160,66 +143,6 @@ const THINKING_SUPPRESSED_OPERATIONS: ReadonlySet<string> = new Set([
160
143
  "hourly_summary_extended",
161
144
  ]);
162
145
 
163
- interface LocalServerConfig {
164
- type: LocalLlmType;
165
- defaultPort: number;
166
- healthEndpoint: string;
167
- modelsEndpoint: string;
168
- detectFn: (response: unknown) => boolean;
169
- }
170
-
171
- const LOCAL_SERVERS: LocalServerConfig[] = [
172
- {
173
- type: "ollama",
174
- defaultPort: 11434,
175
- healthEndpoint: "/",
176
- modelsEndpoint: "/api/tags",
177
- detectFn: (resp) => typeof resp === "string" && resp.includes("Ollama"),
178
- },
179
- {
180
- type: "llamacpp",
181
- defaultPort: 8080,
182
- healthEndpoint: "/health",
183
- modelsEndpoint: "/v1/models",
184
- detectFn: (resp) => isObjectRecord(resp) && resp.status === "ok",
185
- },
186
- {
187
- type: "mlx",
188
- defaultPort: 8080,
189
- healthEndpoint: "/v1/models",
190
- modelsEndpoint: "/v1/models",
191
- detectFn: (resp) => isObjectRecord(resp) && Array.isArray(resp.data),
192
- },
193
- {
194
- type: "lmstudio",
195
- defaultPort: 1234,
196
- healthEndpoint: "/v1/models",
197
- modelsEndpoint: "/v1/models",
198
- detectFn: (resp) => isObjectRecord(resp) && Array.isArray(resp.data),
199
- },
200
- {
201
- type: "vllm",
202
- defaultPort: 8000,
203
- healthEndpoint: "/health",
204
- modelsEndpoint: "/v1/models",
205
- detectFn: (resp) => resp === "" || (isObjectRecord(resp) && !("status" in resp)),
206
- },
207
- ];
208
-
209
- function orderedLocalServers(configuredBaseUrl: string): LocalServerConfig[] {
210
- const configuredPort = explicitPortFromUrl(configuredBaseUrl);
211
- if (configuredPort === null) return LOCAL_SERVERS;
212
- const matching = LOCAL_SERVERS.filter(
213
- (serverConfig) => serverConfig.defaultPort === configuredPort,
214
- );
215
- if (matching.length === 0) return LOCAL_SERVERS;
216
- const matchingTypes = new Set(matching.map((serverConfig) => serverConfig.type));
217
- return [
218
- ...matching,
219
- ...LOCAL_SERVERS.filter((serverConfig) => !matchingTypes.has(serverConfig.type)),
220
- ];
221
- }
222
-
223
146
  export interface LocalModelInfo {
224
147
  id: string;
225
148
  contextWindow?: number;
@@ -244,6 +167,13 @@ type LocalLlmBackendState = {
244
167
  untilMs: number;
245
168
  reason: string;
246
169
  };
170
+ /**
171
+ * Local LLM client for OpenAI-compatible endpoints (LM Studio, Ollama, MLX, etc.)
172
+ *
173
+ * Based on openclaw-tactician's provider detection patterns for consistency.
174
+ * Provides privacy-preserving, cost-effective LLM operations with
175
+ * graceful fallback to cloud providers when local LLM is unavailable.
176
+ */
247
177
  export class LocalLlmClient {
248
178
  private config: PluginConfig;
249
179
  private isAvailable: boolean | null = null;
@@ -435,6 +365,16 @@ export class LocalLlmClient {
435
365
  // is down (issue #2210). Tracked separately so a loaded daemon cannot cache
436
366
  // itself into a blackout.
437
367
  let sawAbortedProbe = false;
368
+ // Several server shapes share a probe URL (LiteLLM and Ollama both use
369
+ // `/`); fetch each URL once per pass.
370
+ const probed = new Map<string, ProbeFetchResult>();
371
+ const probeOnce = async (url: string): Promise<ProbeFetchResult> => {
372
+ const cached = probed.get(url);
373
+ if (cached) return cached;
374
+ const result = await this.fetchWithTimeout(url, 2000, undefined, signal);
375
+ probed.set(url, result);
376
+ return result;
377
+ };
438
378
 
439
379
  // Try to detect which server type is running
440
380
  if (signal?.aborted) return false;
@@ -442,7 +382,7 @@ export class LocalLlmClient {
442
382
  const healthUrl = `${probeBaseUrl}${serverConfig.healthEndpoint}`;
443
383
  log.debug(`checking ${serverConfig.type} at ${healthUrl}`);
444
384
 
445
- const result = await this.fetchWithTimeout(healthUrl, 2000, undefined, signal);
385
+ const result = await probeOnce(healthUrl);
446
386
  if (result.aborted) sawAbortedProbe = true;
447
387
  if (signal?.aborted) return false;
448
388
  if (result.ok && serverConfig.detectFn(result.data)) {