@remnic/core 10.0.35 → 10.0.36

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 (91) hide show
  1. package/dist/access-admin-ops-surface.js +5 -5
  2. package/dist/access-authorization-probe.js +6 -6
  3. package/dist/access-boundary.js +5 -5
  4. package/dist/access-cli.js +23 -23
  5. package/dist/access-extraction-force-flush.js +5 -5
  6. package/dist/access-http-briefing.js +6 -6
  7. package/dist/access-http-query.js +5 -5
  8. package/dist/access-http.js +17 -17
  9. package/dist/access-identity-continuity-surface.js +5 -5
  10. package/dist/access-lcm-surface.js +5 -5
  11. package/dist/access-mcp.js +12 -12
  12. package/dist/access-namespace-preflight.js +5 -5
  13. package/dist/access-observe-write-surface.js +5 -5
  14. package/dist/access-operations-batch.js +6 -6
  15. package/dist/access-operations.js +11 -11
  16. package/dist/access-recall-concurrency.js +5 -5
  17. package/dist/access-recall-response.js +5 -5
  18. package/dist/access-recall-surface.js +5 -5
  19. package/dist/access-service.js +5 -5
  20. package/dist/access-surface-catalog.js +7 -7
  21. package/dist/calibration.js +3 -3
  22. package/dist/{chunk-SXRX6K35.js → chunk-4YYIZ475.js} +3 -3
  23. package/dist/{chunk-OLAQWYNF.js → chunk-5XTSIZ3L.js} +3 -3
  24. package/dist/{chunk-JUXOTY6J.js → chunk-5YQXWVCP.js} +9 -2
  25. package/dist/chunk-5YQXWVCP.js.map +1 -0
  26. package/dist/{chunk-GK56GNNS.js → chunk-65JLKIVA.js} +2 -2
  27. package/dist/{chunk-SQ554O3K.js → chunk-74AY3S7U.js} +3 -3
  28. package/dist/{chunk-MGXLLL5L.js → chunk-AD3ZB72W.js} +2 -2
  29. package/dist/{chunk-FW7KWZBI.js → chunk-F2JLBXMG.js} +2 -2
  30. package/dist/{chunk-D75ET36O.js → chunk-FL6SLVAJ.js} +2 -2
  31. package/dist/{chunk-JJWOKRZA.js → chunk-IKCGNTGS.js} +2 -2
  32. package/dist/{chunk-CM6JDFCN.js → chunk-KQUN4RSX.js} +8 -8
  33. package/dist/{chunk-NLQBTHBV.js → chunk-LJSBF6PW.js} +2 -2
  34. package/dist/{chunk-GRBQO56D.js → chunk-NBH7IRME.js} +4 -4
  35. package/dist/{chunk-6NAN4WFY.js → chunk-NDJ42GKB.js} +2 -2
  36. package/dist/{chunk-HT6IEMQ2.js → chunk-NIANATGL.js} +2 -2
  37. package/dist/{chunk-GQVTALUJ.js → chunk-OHMGR6QN.js} +2 -2
  38. package/dist/{chunk-4LOMATQA.js → chunk-PDYP7SUC.js} +2 -2
  39. package/dist/{chunk-TVM47JQB.js → chunk-RYUSWAAU.js} +1 -1
  40. package/dist/{chunk-MLED254J.js → chunk-T6OZW2WR.js} +8 -2
  41. package/dist/chunk-T6OZW2WR.js.map +1 -0
  42. package/dist/{chunk-ZRU7636R.js → chunk-V3JZZJ2E.js} +3 -3
  43. package/dist/{chunk-G2PC6IZB.js → chunk-VKB2FGNW.js} +9 -9
  44. package/dist/{chunk-KVNOHMVE.js → chunk-X544TW54.js} +2 -2
  45. package/dist/{chunk-GRZX3RHY.js → chunk-XO4HOBM2.js} +2 -2
  46. package/dist/{chunk-P2RCFQA6.js → chunk-ZSAQSLKL.js} +2 -2
  47. package/dist/cli.js +18 -18
  48. package/dist/compounding/engine.js +1 -1
  49. package/dist/external-wiki-access.js +6 -6
  50. package/dist/extraction.js +4 -4
  51. package/dist/index.js +23 -23
  52. package/dist/local-llm-helpers.d.ts.map +1 -1
  53. package/dist/local-llm-helpers.js +2 -1
  54. package/dist/local-llm-transport.d.ts +1 -0
  55. package/dist/local-llm-transport.d.ts.map +1 -1
  56. package/dist/local-llm-transport.js +5 -3
  57. package/dist/local-llm.js +3 -3
  58. package/dist/memory-browse-operations.js +6 -6
  59. package/dist/orchestration/maintenance.js +5 -5
  60. package/dist/orchestrator.js +23 -23
  61. package/dist/recall-navigation-operations.js +6 -6
  62. package/dist/recall-navigation.js +5 -5
  63. package/dist/summarizer.js +4 -4
  64. package/dist/support-passport/index.js +8 -8
  65. package/package.json +2 -2
  66. package/src/local-llm-headers-timeout.test.ts +64 -0
  67. package/src/local-llm-helpers.ts +6 -1
  68. package/src/local-llm-transport.ts +14 -1
  69. package/dist/chunk-JUXOTY6J.js.map +0 -1
  70. package/dist/chunk-MLED254J.js.map +0 -1
  71. /package/dist/{chunk-SXRX6K35.js.map → chunk-4YYIZ475.js.map} +0 -0
  72. /package/dist/{chunk-OLAQWYNF.js.map → chunk-5XTSIZ3L.js.map} +0 -0
  73. /package/dist/{chunk-GK56GNNS.js.map → chunk-65JLKIVA.js.map} +0 -0
  74. /package/dist/{chunk-SQ554O3K.js.map → chunk-74AY3S7U.js.map} +0 -0
  75. /package/dist/{chunk-MGXLLL5L.js.map → chunk-AD3ZB72W.js.map} +0 -0
  76. /package/dist/{chunk-FW7KWZBI.js.map → chunk-F2JLBXMG.js.map} +0 -0
  77. /package/dist/{chunk-D75ET36O.js.map → chunk-FL6SLVAJ.js.map} +0 -0
  78. /package/dist/{chunk-JJWOKRZA.js.map → chunk-IKCGNTGS.js.map} +0 -0
  79. /package/dist/{chunk-CM6JDFCN.js.map → chunk-KQUN4RSX.js.map} +0 -0
  80. /package/dist/{chunk-NLQBTHBV.js.map → chunk-LJSBF6PW.js.map} +0 -0
  81. /package/dist/{chunk-GRBQO56D.js.map → chunk-NBH7IRME.js.map} +0 -0
  82. /package/dist/{chunk-6NAN4WFY.js.map → chunk-NDJ42GKB.js.map} +0 -0
  83. /package/dist/{chunk-HT6IEMQ2.js.map → chunk-NIANATGL.js.map} +0 -0
  84. /package/dist/{chunk-GQVTALUJ.js.map → chunk-OHMGR6QN.js.map} +0 -0
  85. /package/dist/{chunk-4LOMATQA.js.map → chunk-PDYP7SUC.js.map} +0 -0
  86. /package/dist/{chunk-TVM47JQB.js.map → chunk-RYUSWAAU.js.map} +0 -0
  87. /package/dist/{chunk-ZRU7636R.js.map → chunk-V3JZZJ2E.js.map} +0 -0
  88. /package/dist/{chunk-G2PC6IZB.js.map → chunk-VKB2FGNW.js.map} +0 -0
  89. /package/dist/{chunk-KVNOHMVE.js.map → chunk-X544TW54.js.map} +0 -0
  90. /package/dist/{chunk-GRZX3RHY.js.map → chunk-XO4HOBM2.js.map} +0 -0
  91. /package/dist/{chunk-P2RCFQA6.js.map → chunk-ZSAQSLKL.js.map} +0 -0
@@ -4,13 +4,13 @@ import {
4
4
  graphPathRelativeToStorage,
5
5
  mergeGraphExpandedResults,
6
6
  qmdStartupCollectionChecksWithTimeout
7
- } from "./chunk-G2PC6IZB.js";
7
+ } from "./chunk-VKB2FGNW.js";
8
8
  import "./chunk-XFDHL252.js";
9
- import "./chunk-JJWOKRZA.js";
9
+ import "./chunk-IKCGNTGS.js";
10
10
  import {
11
11
  formatCompressionGuidelinesForRecall
12
12
  } from "./chunk-5PHOU5QI.js";
13
- import "./chunk-ZRU7636R.js";
13
+ import "./chunk-V3JZZJ2E.js";
14
14
  import "./chunk-I74SUMNI.js";
15
15
  import "./chunk-ILNPU5W5.js";
16
16
  import "./chunk-VZAKYDMJ.js";
@@ -31,7 +31,7 @@ import "./chunk-7N4KAIGN.js";
31
31
  import "./chunk-V5OCT34X.js";
32
32
  import "./chunk-TECVW3JP.js";
33
33
  import "./chunk-C5JF6EZ7.js";
34
- import "./chunk-TVM47JQB.js";
34
+ import "./chunk-RYUSWAAU.js";
35
35
  import "./chunk-5KBIOI4G.js";
36
36
  import "./chunk-3Q3XD3NO.js";
37
37
  import "./chunk-YLF42JQ7.js";
@@ -74,7 +74,7 @@ import "./chunk-PHRLJFWZ.js";
74
74
  import "./chunk-64NJRYU2.js";
75
75
  import "./chunk-LQ5SS4OP.js";
76
76
  import "./chunk-XXSOVESA.js";
77
- import "./chunk-GK56GNNS.js";
77
+ import "./chunk-65JLKIVA.js";
78
78
  import "./chunk-K567EIW3.js";
79
79
  import "./chunk-54V4BZWP.js";
80
80
  import "./chunk-2CGLBUW3.js";
@@ -121,7 +121,7 @@ import "./chunk-GAARPWMN.js";
121
121
  import "./chunk-7G5NTS7F.js";
122
122
  import "./chunk-4NZQ7IID.js";
123
123
  import "./chunk-3I4FUAVJ.js";
124
- import "./chunk-GRBQO56D.js";
124
+ import "./chunk-NBH7IRME.js";
125
125
  import "./chunk-H4CKS5B2.js";
126
126
  import "./chunk-MMACM5G2.js";
127
127
  import "./chunk-54BGIBCR.js";
@@ -235,7 +235,7 @@ import "./chunk-27NO2KVB.js";
235
235
  import "./chunk-KFZY2OFH.js";
236
236
  import "./chunk-B32WYRXX.js";
237
237
  import "./chunk-QW27DOHG.js";
238
- import "./chunk-CM6JDFCN.js";
238
+ import "./chunk-KQUN4RSX.js";
239
239
  import "./chunk-V7IZKJI3.js";
240
240
  import "./chunk-XW2T4QAW.js";
241
241
  import "./chunk-G3T6YMBO.js";
@@ -249,10 +249,10 @@ import "./chunk-ZSEFGDCI.js";
249
249
  import "./chunk-P6P35FY4.js";
250
250
  import "./chunk-3HSRWJTC.js";
251
251
  import "./chunk-AHS3QEEA.js";
252
- import "./chunk-GRZX3RHY.js";
253
- import "./chunk-KVNOHMVE.js";
252
+ import "./chunk-XO4HOBM2.js";
253
+ import "./chunk-X544TW54.js";
254
254
  import "./chunk-SRT6SHVZ.js";
255
- import "./chunk-6NAN4WFY.js";
255
+ import "./chunk-NDJ42GKB.js";
256
256
  import "./chunk-TE6S7KDF.js";
257
257
  import "./chunk-MZUQVWVC.js";
258
258
  import "./chunk-EIB4FJVR.js";
@@ -260,16 +260,16 @@ import "./chunk-A5KNZSNA.js";
260
260
  import "./chunk-HUSTM6PU.js";
261
261
  import "./chunk-D24OXEPB.js";
262
262
  import "./chunk-64IO6ZEE.js";
263
- import "./chunk-OLAQWYNF.js";
263
+ import "./chunk-5XTSIZ3L.js";
264
264
  import "./chunk-QQ4T622E.js";
265
- import "./chunk-HT6IEMQ2.js";
265
+ import "./chunk-NIANATGL.js";
266
266
  import "./chunk-M3GKSCFN.js";
267
- import "./chunk-MGXLLL5L.js";
268
- import "./chunk-GQVTALUJ.js";
269
- import "./chunk-P2RCFQA6.js";
267
+ import "./chunk-AD3ZB72W.js";
268
+ import "./chunk-OHMGR6QN.js";
269
+ import "./chunk-ZSAQSLKL.js";
270
270
  import "./chunk-7T4TOGMS.js";
271
271
  import "./chunk-7YQ6ESEA.js";
272
- import "./chunk-FW7KWZBI.js";
272
+ import "./chunk-F2JLBXMG.js";
273
273
  import "./chunk-GDYLZ6FR.js";
274
274
  import "./chunk-PQM3B54K.js";
275
275
  import "./chunk-5LWODP5R.js";
@@ -284,14 +284,14 @@ import "./chunk-DFP37GUN.js";
284
284
  import "./chunk-4ISHIPOC.js";
285
285
  import "./chunk-AB3A7EFH.js";
286
286
  import "./chunk-KIUVEMBI.js";
287
- import "./chunk-NLQBTHBV.js";
287
+ import "./chunk-LJSBF6PW.js";
288
288
  import "./chunk-2BPPGNAQ.js";
289
289
  import "./chunk-DJSJ4ULL.js";
290
- import "./chunk-4LOMATQA.js";
290
+ import "./chunk-PDYP7SUC.js";
291
291
  import {
292
292
  hasIdentityRecoveryIntent,
293
293
  resolveEffectiveIdentityInjectionMode
294
- } from "./chunk-SXRX6K35.js";
294
+ } from "./chunk-4YYIZ475.js";
295
295
  import "./chunk-W4F3C7N7.js";
296
296
  import "./chunk-MPC7TYTZ.js";
297
297
  import "./chunk-STM4T335.js";
@@ -304,7 +304,7 @@ import "./chunk-BRZRP5WD.js";
304
304
  import "./chunk-GNVZQ5JN.js";
305
305
  import "./chunk-YN2UN7N3.js";
306
306
  import "./chunk-JWX2Q6HS.js";
307
- import "./chunk-D75ET36O.js";
307
+ import "./chunk-FL6SLVAJ.js";
308
308
  import "./chunk-53OWLEAD.js";
309
309
  import "./chunk-WWDO7ZWM.js";
310
310
  import "./chunk-R4SATHCV.js";
@@ -368,11 +368,11 @@ import "./chunk-2LSZVONP.js";
368
368
  import "./chunk-DEUNUKTD.js";
369
369
  import "./chunk-LXY5VVGM.js";
370
370
  import "./chunk-GKCXTSFF.js";
371
- import "./chunk-SQ554O3K.js";
372
- import "./chunk-MLED254J.js";
371
+ import "./chunk-74AY3S7U.js";
372
+ import "./chunk-T6OZW2WR.js";
373
373
  import "./chunk-QEDLJDHP.js";
374
374
  import "./chunk-U4LUIE6Y.js";
375
- import "./chunk-JUXOTY6J.js";
375
+ import "./chunk-5YQXWVCP.js";
376
376
  import "./chunk-ZY2MNJR6.js";
377
377
  import "./chunk-7WTTE5FW.js";
378
378
  import "./chunk-3UXOZBHV.js";
@@ -1,5 +1,5 @@
1
- import "./chunk-MGXLLL5L.js";
2
- import "./chunk-SXRX6K35.js";
1
+ import "./chunk-AD3ZB72W.js";
2
+ import "./chunk-4YYIZ475.js";
3
3
  import "./chunk-W4F3C7N7.js";
4
4
  import "./chunk-MPC7TYTZ.js";
5
5
  import "./chunk-STM4T335.js";
@@ -12,7 +12,7 @@ import "./chunk-BRZRP5WD.js";
12
12
  import "./chunk-GNVZQ5JN.js";
13
13
  import "./chunk-YN2UN7N3.js";
14
14
  import "./chunk-JWX2Q6HS.js";
15
- import "./chunk-D75ET36O.js";
15
+ import "./chunk-FL6SLVAJ.js";
16
16
  import "./chunk-53OWLEAD.js";
17
17
  import "./chunk-WWDO7ZWM.js";
18
18
  import "./chunk-R4SATHCV.js";
@@ -74,11 +74,11 @@ import "./chunk-2LSZVONP.js";
74
74
  import "./chunk-DEUNUKTD.js";
75
75
  import "./chunk-LXY5VVGM.js";
76
76
  import "./chunk-GKCXTSFF.js";
77
- import "./chunk-SQ554O3K.js";
78
- import "./chunk-MLED254J.js";
77
+ import "./chunk-74AY3S7U.js";
78
+ import "./chunk-T6OZW2WR.js";
79
79
  import "./chunk-QEDLJDHP.js";
80
80
  import "./chunk-U4LUIE6Y.js";
81
- import "./chunk-JUXOTY6J.js";
81
+ import "./chunk-5YQXWVCP.js";
82
82
  import "./chunk-ZY2MNJR6.js";
83
83
  import "./chunk-7WTTE5FW.js";
84
84
  import "./chunk-3UXOZBHV.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runRecallNavigation
3
- } from "./chunk-SXRX6K35.js";
3
+ } from "./chunk-4YYIZ475.js";
4
4
  import "./chunk-W4F3C7N7.js";
5
5
  import "./chunk-MPC7TYTZ.js";
6
6
  import "./chunk-STM4T335.js";
@@ -13,7 +13,7 @@ import "./chunk-BRZRP5WD.js";
13
13
  import "./chunk-GNVZQ5JN.js";
14
14
  import "./chunk-YN2UN7N3.js";
15
15
  import "./chunk-JWX2Q6HS.js";
16
- import "./chunk-D75ET36O.js";
16
+ import "./chunk-FL6SLVAJ.js";
17
17
  import "./chunk-53OWLEAD.js";
18
18
  import "./chunk-WWDO7ZWM.js";
19
19
  import "./chunk-R4SATHCV.js";
@@ -75,11 +75,11 @@ import "./chunk-2LSZVONP.js";
75
75
  import "./chunk-DEUNUKTD.js";
76
76
  import "./chunk-LXY5VVGM.js";
77
77
  import "./chunk-GKCXTSFF.js";
78
- import "./chunk-SQ554O3K.js";
79
- import "./chunk-MLED254J.js";
78
+ import "./chunk-74AY3S7U.js";
79
+ import "./chunk-T6OZW2WR.js";
80
80
  import "./chunk-QEDLJDHP.js";
81
81
  import "./chunk-U4LUIE6Y.js";
82
- import "./chunk-JUXOTY6J.js";
82
+ import "./chunk-5YQXWVCP.js";
83
83
  import "./chunk-ZY2MNJR6.js";
84
84
  import "./chunk-7WTTE5FW.js";
85
85
  import "./chunk-3UXOZBHV.js";
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  HourlySummarizer,
3
3
  summarizeHourlyStatus
4
- } from "./chunk-D75ET36O.js";
4
+ } from "./chunk-FL6SLVAJ.js";
5
5
  import "./chunk-53OWLEAD.js";
6
6
  import "./chunk-5Y43VGYB.js";
7
7
  import "./chunk-5MA7ZLPD.js";
8
- import "./chunk-SQ554O3K.js";
9
- import "./chunk-MLED254J.js";
8
+ import "./chunk-74AY3S7U.js";
9
+ import "./chunk-T6OZW2WR.js";
10
10
  import "./chunk-QEDLJDHP.js";
11
11
  import "./chunk-U4LUIE6Y.js";
12
- import "./chunk-JUXOTY6J.js";
12
+ import "./chunk-5YQXWVCP.js";
13
13
  import "./chunk-KF7PQ7G2.js";
14
14
  import "./chunk-TOTT6S2V.js";
15
15
  import "./chunk-GMMZ45C4.js";
@@ -4,7 +4,7 @@ import {
4
4
  SUPPORT_PASSPORT_MODEL_RESULT_PATH,
5
5
  SupportPassportModelBridge,
6
6
  parseSupportPassportModelJob
7
- } from "../chunk-JJWOKRZA.js";
7
+ } from "../chunk-IKCGNTGS.js";
8
8
  import {
9
9
  DEFAULT_SUPPORT_PASSPORT_CONFIG,
10
10
  parseSupportPassportConfig
@@ -14,8 +14,8 @@ import {
14
14
  buildSupportPassportPublicRequestHandler,
15
15
  composeSupportPassportExternalRequestHandlers,
16
16
  normalizeSupportPassportNetworkAddress
17
- } from "../chunk-KVNOHMVE.js";
18
- import "../chunk-HT6IEMQ2.js";
17
+ } from "../chunk-X544TW54.js";
18
+ import "../chunk-NIANATGL.js";
19
19
  import {
20
20
  SUPPORT_PASSPORT_DRAFT_MAX_CONTENT_CHARACTERS,
21
21
  SUPPORT_PASSPORT_DRAFT_MAX_MEMORIES,
@@ -56,7 +56,7 @@ import {
56
56
  notifySupportPassportCommitted,
57
57
  resolveSupportPassportModelRoutePlan,
58
58
  syncDirectoryForDurability
59
- } from "../chunk-SXRX6K35.js";
59
+ } from "../chunk-4YYIZ475.js";
60
60
  import "../chunk-W4F3C7N7.js";
61
61
  import "../chunk-MPC7TYTZ.js";
62
62
  import "../chunk-STM4T335.js";
@@ -69,7 +69,7 @@ import "../chunk-BRZRP5WD.js";
69
69
  import "../chunk-GNVZQ5JN.js";
70
70
  import "../chunk-YN2UN7N3.js";
71
71
  import "../chunk-JWX2Q6HS.js";
72
- import "../chunk-D75ET36O.js";
72
+ import "../chunk-FL6SLVAJ.js";
73
73
  import "../chunk-53OWLEAD.js";
74
74
  import "../chunk-WWDO7ZWM.js";
75
75
  import "../chunk-R4SATHCV.js";
@@ -131,11 +131,11 @@ import "../chunk-2LSZVONP.js";
131
131
  import "../chunk-DEUNUKTD.js";
132
132
  import "../chunk-LXY5VVGM.js";
133
133
  import "../chunk-GKCXTSFF.js";
134
- import "../chunk-SQ554O3K.js";
135
- import "../chunk-MLED254J.js";
134
+ import "../chunk-74AY3S7U.js";
135
+ import "../chunk-T6OZW2WR.js";
136
136
  import "../chunk-QEDLJDHP.js";
137
137
  import "../chunk-U4LUIE6Y.js";
138
- import "../chunk-JUXOTY6J.js";
138
+ import "../chunk-5YQXWVCP.js";
139
139
  import "../chunk-ZY2MNJR6.js";
140
140
  import "../chunk-7WTTE5FW.js";
141
141
  import "../chunk-3UXOZBHV.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "10.0.35",
3
+ "version": "10.0.36",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -3347,7 +3347,7 @@
3347
3347
  "core"
3348
3348
  ],
3349
3349
  "peerDependencies": {
3350
- "@remnic/coding-graph": "^10.0.35"
3350
+ "@remnic/coding-graph": "^10.0.36"
3351
3351
  },
3352
3352
  "peerDependenciesMeta": {
3353
3353
  "@remnic/coding-graph": {
@@ -12,6 +12,7 @@ import {
12
12
  } from "undici";
13
13
 
14
14
  import { LocalLlmClient } from "./local-llm.js";
15
+ import { probeFetch } from "./local-llm-helpers.js";
15
16
  import { classifyAnalysisProviderError } from "./activity/timeline/analysis-provider.js";
16
17
  import { ChatTransport } from "./local-llm-transport.js";
17
18
  import { initLogger, resetLogger } from "./logger.js";
@@ -466,6 +467,69 @@ test("a process-wide custom dispatcher is left in place", async () => {
466
467
  await restored.close();
467
468
  });
468
469
 
470
+ test("an explicit opt-in widens the pool even when a custom global dispatcher is installed", async () => {
471
+ // Some hosts install a process-wide dispatcher (for example an agent runtime's
472
+ // managed proxy) that is unrelated to the LAN model server. There the 300s
473
+ // header cap stood silently and every slow completion died with `fetch failed`
474
+ // at 301s. REMNIC_LOCAL_LLM_DIRECT=1 declares that the local endpoint is
475
+ // reached directly, so the transport uses its own pool. Without the flag the
476
+ // previous behavior (leave the custom dispatcher alone) is unchanged.
477
+ const original = getGlobalDispatcher();
478
+ const proxy = new ProxyAgent("http://127.0.0.1:9");
479
+ const priorFlag = process.env.REMNIC_LOCAL_LLM_DIRECT;
480
+ try {
481
+ setGlobalDispatcher(proxy);
482
+ delete process.env.REMNIC_LOCAL_LLM_DIRECT;
483
+ assert.equal(new ChatTransport().dispatcherFor(900_000), undefined, "no flag: custom dispatcher stays");
484
+
485
+ process.env.REMNIC_LOCAL_LLM_DIRECT = "1";
486
+ const transport = new ChatTransport();
487
+ const agent = transport.dispatcherFor(900_000);
488
+ assert.ok(agent instanceof Agent, "flag set: the widened pool must be used");
489
+ assert.ok(!(agent instanceof ProxyAgent), "flag set: the proxy dispatcher must not be used");
490
+ await agent.close();
491
+
492
+ process.env.REMNIC_LOCAL_LLM_DIRECT = "0";
493
+ assert.equal(new ChatTransport().dispatcherFor(900_000), undefined, "flag 0: custom dispatcher stays");
494
+ } finally {
495
+ if (priorFlag === undefined) delete process.env.REMNIC_LOCAL_LLM_DIRECT;
496
+ else process.env.REMNIC_LOCAL_LLM_DIRECT = priorFlag;
497
+ setGlobalDispatcher(original);
498
+ await proxy.close();
499
+ }
500
+ });
501
+
502
+ test("REMNIC_LOCAL_LLM_DIRECT=1 also sends availability probes around a global proxy dispatcher", async () => {
503
+ // A host whose global dispatcher cannot reach the LAN model server would fail
504
+ // checkAvailability() before any chat request runs, so direct mode must cover
505
+ // the probe as well as ChatTransport.post.
506
+ const server = http.createServer((_req, res) => {
507
+ res.setHeader("content-type", "application/json");
508
+ res.end('{"data":[]}');
509
+ });
510
+ await new Promise<void>((resolve) => server.listen(0, "127.0.0.1", resolve));
511
+ // SAFETY: listen(0, "127.0.0.1") above binds a TCP port, so address() is an AddressInfo, never a pipe string or null.
512
+ const { port } = server.address() as AddressInfo;
513
+ const url = `http://127.0.0.1:${port}/v1/models`;
514
+ const original = getGlobalDispatcher();
515
+ const priorFlag = process.env.REMNIC_LOCAL_LLM_DIRECT;
516
+ try {
517
+ setGlobalDispatcher(new ProxyAgent("http://127.0.0.1:9"));
518
+ delete process.env.REMNIC_LOCAL_LLM_DIRECT;
519
+ const viaProxy = await probeFetch(url, { timeoutMs: 2_000, headers: {} });
520
+ assert.equal(viaProxy.ok, false, "no flag: the probe goes through the (unreachable) proxy");
521
+
522
+ process.env.REMNIC_LOCAL_LLM_DIRECT = "1";
523
+ const direct = await probeFetch(url, { timeoutMs: 2_000, headers: {} });
524
+ assert.equal(direct.ok, true, "flag set: the probe reaches the endpoint directly");
525
+ } finally {
526
+ if (priorFlag === undefined) delete process.env.REMNIC_LOCAL_LLM_DIRECT;
527
+ else process.env.REMNIC_LOCAL_LLM_DIRECT = priorFlag;
528
+ setGlobalDispatcher(original);
529
+ await new Promise<void>((resolve) => server.close(() => resolve()));
530
+ }
531
+ });
532
+
469
533
  test("aborting during a retry backoff stops the local request lane", async () => {
470
534
  const original = globalThis.fetch;
471
535
  const abortController = new AbortController();
@@ -1,5 +1,7 @@
1
1
  import type { ResponseFormatJSONSchema } from "openai/resources/shared";
2
+ import type { Agent } from "undici";
2
3
  import { log } from "./logger.js";
4
+ import { directProbeDispatcher } from "./local-llm-transport.js";
3
5
  import type { LocalLlmRequestPriority } from "./local-llm.js";
4
6
 
5
7
  export interface LocalLlmChatCompletionOptions {
@@ -167,7 +169,10 @@ export async function probeFetch(
167
169
  : controller.signal;
168
170
  const timeout = setTimeout(() => controller.abort(), options.timeoutMs);
169
171
  try {
170
- const response = await fetch(url, { signal: requestSignal, headers: options.headers });
172
+ const init: RequestInit & { dispatcher?: Agent } = { signal: requestSignal, headers: options.headers };
173
+ const dispatcher = directProbeDispatcher();
174
+ if (dispatcher) init.dispatcher = dispatcher;
175
+ const response = await fetch(url, init);
171
176
  clearTimeout(timeout);
172
177
  if (!response.ok) {
173
178
  log.debug(`local LLM probe: ${url} returned HTTP ${response.status}`);
@@ -40,6 +40,18 @@ function isPlainPoolingAgent(dispatcher: unknown): boolean {
40
40
  return ctor.name === "Agent";
41
41
  }
42
42
 
43
+ /**
44
+ * REMNIC_LOCAL_LLM_DIRECT=1 declares that the local endpoint is reached
45
+ * directly. Availability probes use this shared plain pool in that mode so they
46
+ * take the same route as chat requests; `undefined` keeps the global dispatcher.
47
+ */
48
+ let directProbeAgent: Agent | null = null;
49
+ export function directProbeDispatcher(): Agent | undefined {
50
+ if (process.env.REMNIC_LOCAL_LLM_DIRECT !== "1") return undefined;
51
+ directProbeAgent ??= new Agent();
52
+ return directProbeAgent;
53
+ }
54
+
43
55
  /**
44
56
  * Connection pool whose header/body inactivity budgets track the configured
45
57
  * request budget.
@@ -72,7 +84,8 @@ export class ChatTransport {
72
84
  * because only the dispatcher's owner knows how to rebuild it.
73
85
  */
74
86
  dispatcherFor(budgetMs: number): Agent | undefined {
75
- if (!isPlainPoolingAgent(getGlobalDispatcher())) {
87
+ // REMNIC_LOCAL_LLM_DIRECT=1: the operator declares the local endpoint is reached directly even though the process installed a global dispatcher for other traffic (an agent runtime's managed proxy). Without it the 300s header cap stands silently on such hosts and every completion slower than five minutes dies with `fetch failed`. Off by default so deployments that must use a proxy keep it.
88
+ if (!isPlainPoolingAgent(getGlobalDispatcher()) && process.env.REMNIC_LOCAL_LLM_DIRECT !== "1") {
76
89
  if (!this.warnedAboutCustomDispatcher) {
77
90
  this.warnedAboutCustomDispatcher = true;
78
91
  log.debug(
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/local-llm-transport.ts"],"sourcesContent":["import { Agent, getGlobalDispatcher } from \"undici\";\n\nimport { log } from \"./logger.js\";\n\n/**\n * Wire transport for local LLM chat completions.\n *\n * Split out of `local-llm.ts` so the client module keeps prompt and\n * response semantics while connection budgets live in one place.\n */\n\nexport interface ChatCompletionRequest {\n url: string;\n headers: Record<string, string>;\n body: string;\n signal: AbortSignal;\n /**\n * Ceiling for this endpoint, i.e. `localLlmTimeoutMs`. Sizes the\n * connection's inactivity budgets. Per-request budgets below the ceiling\n * stay enforced by `signal`.\n */\n budgetMs: number;\n}\n\n/**\n * Is this undici's stock pooling `Agent` — the transport we may widen?\n *\n * `instanceof` alone is not enough: Node's global fetch is backed by its\n * OWN bundled copy of undici, so the dispatcher parked on the well-known\n * global symbol is an `Agent` from a different copy than the one we import,\n * and cross-copy `instanceof` is false. Fall back to the constructor name,\n * which is stable across copies and still distinguishes `ProxyAgent` and\n * `MockAgent` from the stock pool.\n */\nfunction isPlainPoolingAgent(dispatcher: unknown): boolean {\n if (dispatcher instanceof Agent) return true;\n if (!dispatcher || typeof dispatcher !== \"object\") return false;\n const ctor = (dispatcher as { constructor?: unknown }).constructor;\n if (!ctor || typeof ctor !== \"function\") return false;\n return ctor.name === \"Agent\";\n}\n\n/**\n * Connection pool whose header/body inactivity budgets track the configured\n * request budget.\n *\n * Node's global fetch runs on undici, which applies a default\n * `headersTimeout` and `bodyTimeout` of 300s. A non-streaming completion\n * sends its response headers only once generation finishes, so any\n * completion slower than 300s died with a bare `fetch failed` no matter how\n * high `localLlmTimeoutMs` was set — the configured budget was dead letter\n * past five minutes (issue #2148).\n *\n * One pool per client is enough: it is keyed on the ceiling and rebuilt when\n * that changes.\n */\nexport class ChatTransport {\n private agent: Agent | null = null;\n private agentBudgetMs: number | null = null;\n private warnedAboutCustomDispatcher = false;\n\n /**\n * The widened pool, or `undefined` when the process installed its own\n * transport that we must not displace.\n *\n * A deployment can route the local endpoint through a process-wide\n * dispatcher — a `ProxyAgent` for an HTTP proxy, or a custom\n * connect/TLS/DNS dispatcher. Swapping in our own pool would bypass the\n * proxy entirely and break the request, so those are left alone. A\n * `MockAgent` is excluded by the same check, so test transports keep\n * working. The trade-off is explicit: on those setups the 300s cap stands,\n * because only the dispatcher's owner knows how to rebuild it.\n */\n dispatcherFor(budgetMs: number): Agent | undefined {\n if (!isPlainPoolingAgent(getGlobalDispatcher())) {\n if (!this.warnedAboutCustomDispatcher) {\n this.warnedAboutCustomDispatcher = true;\n log.debug(\n \"local LLM: a custom global dispatcher is installed; leaving it in place. \" +\n \"localLlmTimeoutMs above that dispatcher's headersTimeout will not take effect.\",\n );\n }\n return undefined;\n }\n const normalized = Number.isFinite(budgetMs) ? Math.max(0, budgetMs) : 0;\n if (this.agent && this.agentBudgetMs === normalized) return this.agent;\n void this.agent?.close().catch(() => {\n /* pool teardown is best-effort */\n });\n this.agent = new Agent({\n headersTimeout: normalized,\n bodyTimeout: normalized,\n });\n this.agentBudgetMs = normalized;\n return this.agent;\n }\n\n async post(request: ChatCompletionRequest): Promise<Response> {\n const init: RequestInit & { dispatcher?: Agent } = {\n method: \"POST\",\n headers: request.headers,\n body: request.body,\n signal: request.signal,\n };\n const dispatcher = this.dispatcherFor(request.budgetMs);\n if (dispatcher) init.dispatcher = dispatcher;\n return await fetch(request.url, init);\n }\n}\n"],"mappings":";;;;;AAAA,SAAS,OAAO,2BAA2B;AAkC3C,SAAS,oBAAoB,YAA8B;AACzD,MAAI,sBAAsB,MAAO,QAAO;AACxC,MAAI,CAAC,cAAc,OAAO,eAAe,SAAU,QAAO;AAC1D,QAAM,OAAQ,WAAyC;AACvD,MAAI,CAAC,QAAQ,OAAO,SAAS,WAAY,QAAO;AAChD,SAAO,KAAK,SAAS;AACvB;AAgBO,IAAM,gBAAN,MAAoB;AAAA,EACjB,QAAsB;AAAA,EACtB,gBAA+B;AAAA,EAC/B,8BAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EActC,cAAc,UAAqC;AACjD,QAAI,CAAC,oBAAoB,oBAAoB,CAAC,GAAG;AAC/C,UAAI,CAAC,KAAK,6BAA6B;AACrC,aAAK,8BAA8B;AACnC,YAAI;AAAA,UACF;AAAA,QAEF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AACA,UAAM,aAAa,OAAO,SAAS,QAAQ,IAAI,KAAK,IAAI,GAAG,QAAQ,IAAI;AACvE,QAAI,KAAK,SAAS,KAAK,kBAAkB,WAAY,QAAO,KAAK;AACjE,SAAK,KAAK,OAAO,MAAM,EAAE,MAAM,MAAM;AAAA,IAErC,CAAC;AACD,SAAK,QAAQ,IAAI,MAAM;AAAA,MACrB,gBAAgB;AAAA,MAChB,aAAa;AAAA,IACf,CAAC;AACD,SAAK,gBAAgB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,KAAK,SAAmD;AAC5D,UAAM,OAA6C;AAAA,MACjD,QAAQ;AAAA,MACR,SAAS,QAAQ;AAAA,MACjB,MAAM,QAAQ;AAAA,MACd,QAAQ,QAAQ;AAAA,IAClB;AACA,UAAM,aAAa,KAAK,cAAc,QAAQ,QAAQ;AACtD,QAAI,WAAY,MAAK,aAAa;AAClC,WAAO,MAAM,MAAM,QAAQ,KAAK,IAAI;AAAA,EACtC;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/local-llm-helpers.ts"],"sourcesContent":["import type { ResponseFormatJSONSchema } from \"openai/resources/shared\";\nimport { log } from \"./logger.js\";\nimport type { LocalLlmRequestPriority } from \"./local-llm.js\";\n\nexport interface LocalLlmChatCompletionOptions {\n temperature?: number;\n maxTokens?: number;\n responseFormat?: { type: string } | ResponseFormatJSONSchema;\n timeoutMs?: number;\n operation?: string;\n forceDisableThinking?: boolean;\n disableThinking?: boolean;\n priority?: LocalLlmRequestPriority;\n signal?: AbortSignal;\n redactProviderErrors?: boolean;\n /** Per-request model; defaults to config.localLlmModel. */\n model?: string;\n /**\n * Optional out-box for the terminal failure cause (issue #2891): on a\n * failed request the client records the last provider error here so\n * callers can classify it (e.g. HTTP 429 → rate-limited) in memory\n * instead of seeing only null. Never logged.\n */\n failureDiag?: { lastError?: unknown };\n}\n\nexport interface LocalLlmChatCompletionResult {\n content: string;\n usage?: { promptTokens: number; completionTokens: number; totalTokens: number };\n}\nexport function isAbortError(err: unknown): boolean {\n if (!err || typeof err !== \"object\") return false;\n const maybe = err as { name?: string; message?: string };\n return (\n maybe.name === \"AbortError\" ||\n maybe.message === \"This operation was aborted\" ||\n maybe.message === \"The operation was aborted\"\n );\n}\n\nexport function waitForRetryBackoff(backoffMs: number, signal?: AbortSignal): Promise<boolean> {\n return new Promise((resolve) => {\n let settled = false;\n let timer: NodeJS.Timeout | undefined;\n const onAbort = (): void => {\n if (settled) return;\n settled = true;\n if (timer) clearTimeout(timer);\n signal?.removeEventListener(\"abort\", onAbort);\n resolve(false);\n };\n const onTimer = (): void => {\n if (settled) return;\n settled = true;\n signal?.removeEventListener(\"abort\", onAbort);\n resolve(true);\n };\n timer = setTimeout(onTimer, backoffMs);\n if (signal) {\n if (signal.aborted) onAbort();\n else signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n}\n\nexport function normalizeBackendTripReason(reason: string): string {\n const cleaned = reason.replace(/\\s+/g, \" \").replace(/^[-:–—\\s]+/, \"\").trim();\n if (!cleaned) return \"unknown local backend failure\";\n return cleaned.length > 160 ? `${cleaned.slice(0, 157)}...` : cleaned;\n}\n\nexport function extractNonRecoverableBackendReason(reason: string): string | null {\n const match = reason.match(\n /Failed to load model|Library not loaded|different Team IDs|code signature|llm_engine_mlx_amphibian/i,\n );\n return match?.[0] ?? null;\n}\n\nexport function extractNonRecoverableBackendReasonFromErrorText(errorText: string): string | null {\n const directReason = extractNonRecoverableBackendReason(errorText);\n if (directReason) return directReason;\n try {\n const parsed = JSON.parse(errorText) as { error?: { message?: string } };\n return extractNonRecoverableBackendReason(parsed?.error?.message ?? \"\");\n } catch {\n return null;\n }\n}\n\n/**\n * Flatten a fetch rejection into one line, including the `cause` undici hides\n * the real reason behind (`fetch failed` alone says nothing).\n */\nexport function describeFetchFailure(err: unknown): string {\n const name = err instanceof Error ? err.name : \"\";\n const message = err instanceof Error ? err.message : String(err);\n const cause: unknown = err instanceof Error ? (err as Error & { cause?: unknown }).cause : undefined;\n const causeText = cause instanceof Error\n ? ` (cause: ${cause.name}: ${cause.message}${\n typeof (cause as Error & { code?: unknown }).code === \"string\"\n ? ` [${String((cause as Error & { code?: unknown }).code)}]`\n : \"\"\n })`\n : cause === undefined\n ? \"\"\n : ` (cause: ${String(cause)})`;\n return `${name ? `${name}: ` : \"\"}${message}${causeText}`;\n}\n\n/**\n * What to record when every availability probe failed.\n *\n * A probe that TIMED OUT is not evidence the backend is down: the budget is a\n * fixed 2s and a busy event loop can burn it before the socket is scheduled,\n * so the backend looks dead while it answers other callers in single-digit ms.\n * Caching that verdict took extraction offline for a whole health-check\n * interval at a time (issue #2210), so a timeout leaves availability UNKNOWN —\n * this call fails, the next one re-probes instead of reading a stale false.\n *\n * A backend that ANSWERED and said no is a real verdict and stays cached, or\n * the daemon re-probes a known-bad endpoint on every request.\n */\nexport function resolveUnavailableVerdict(args: {\n baseUrl: string;\n sawAbortedProbe: boolean;\n wasAvailable: boolean | null;\n}): { cacheVerdict: boolean; warning: string | null } {\n if (args.sawAbortedProbe) {\n return {\n cacheVerdict: false,\n warning:\n `local LLM availability probe timed out at ${args.baseUrl} (event loop busy?); treating availability as ` +\n \"unknown and re-probing on the next request rather than marking the backend down\",\n };\n }\n return {\n cacheVerdict: true,\n // Surfaced at warn, not debug: extraction stops silently when this flips,\n // and the daemon emits no debug at all unless configured for it.\n warning: args.wasAvailable !== false ? `local LLM became unavailable at ${args.baseUrl}` : null,\n };\n}\n\nexport interface ProbeFetchResult {\n ok: boolean;\n data: unknown;\n status: number | null;\n /** The probe hit its own budget rather than getting an answer. */\n aborted?: boolean;\n}\n\n/**\n * One health-probe request.\n *\n * Every failure is logged with its cause: a transport error and a 404 both\n * returned `ok: false` with nothing recorded, so an unreachable backend was\n * indistinguishable from a wrong path and an availability failure had no\n * diagnosable reason at all (§22, issue #2210).\n */\nexport async function probeFetch(\n url: string,\n options: { timeoutMs: number; headers: Record<string, string>; signal?: AbortSignal },\n): Promise<ProbeFetchResult> {\n const controller = new AbortController();\n const requestSignal = options.signal\n ? AbortSignal.any([options.signal, controller.signal])\n : controller.signal;\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs);\n try {\n const response = await fetch(url, { signal: requestSignal, headers: options.headers });\n clearTimeout(timeout);\n if (!response.ok) {\n log.debug(`local LLM probe: ${url} returned HTTP ${response.status}`);\n return { ok: false, data: null, status: response.status };\n }\n const contentType = response.headers.get(\"content-type\");\n const data = contentType?.includes(\"application/json\") ? await response.json() : await response.text();\n return { ok: true, data, status: response.status };\n } catch (err) {\n clearTimeout(timeout);\n const aborted = isAbortError(err);\n log.debug(\n `local LLM probe: ${url} ${aborted ? `timed out after ${options.timeoutMs}ms` : \"failed\"}: ${describeFetchFailure(err)}`,\n );\n return { ok: false, data: null, status: null, aborted };\n }\n}\n\ninterface PendingProbe {\n promise: Promise<boolean>;\n controller: AbortController;\n /** Callers still awaiting this sequence; at zero the sequence is aborted. */\n waiters: number;\n}\n\n/**\n * Collapses concurrent probe sequences onto one in-flight run.\n *\n * A timed-out availability probe deliberately caches nothing (issue #2210),\n * which removed the false verdict that used to absorb concurrent callers:\n * every queued request would then run its own full probe sequence, on a host\n * already slow enough to blow the probe budget.\n *\n * Cancellation is refcounted rather than shared: one caller walking away must\n * not abort a sequence the others are still waiting on, so the underlying task\n * is aborted only once every waiter has gone.\n */\nexport class SingleFlightProbe {\n private pending: PendingProbe | null = null;\n\n run(task: (signal: AbortSignal) => Promise<boolean>, signal?: AbortSignal): Promise<boolean> {\n let active = this.pending;\n if (!active) {\n const controller = new AbortController();\n const created: PendingProbe = { promise: Promise.resolve(false), controller, waiters: 0 };\n created.promise = task(controller.signal).finally(() => {\n if (this.pending === created) this.pending = null;\n });\n this.pending = created;\n active = created;\n }\n const entry = active;\n entry.waiters += 1;\n let released = false;\n const release = () => {\n if (released) return;\n released = true;\n entry.waiters -= 1;\n if (entry.waiters > 0) return;\n // Detach BEFORE aborting. `pending` would otherwise still point at this\n // doomed entry until the task's own `finally` runs a microtask later, and\n // a caller arriving in that window would join an aborted sequence and\n // read its `false` as a verdict.\n if (this.pending === entry) this.pending = null;\n entry.controller.abort();\n };\n if (!signal) return entry.promise.finally(release);\n return new Promise<boolean>((resolve, reject) => {\n const onAbort = () => {\n release();\n resolve(false);\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n entry.promise.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n release();\n resolve(value);\n },\n (err: unknown) => {\n signal.removeEventListener(\"abort\", onAbort);\n release();\n reject(err instanceof Error ? err : new Error(String(err)));\n },\n );\n });\n }\n}\n"],"mappings":"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","names":[]}