@vybestack/llxprt-code-core 0.11.0 → 0.12.0-nightly.260910.2aac6841e

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 (417) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/prompt-config/defaults/default-prompts.json +3 -3
  5. package/dist/src/config/agentClientLifecycle.d.ts +4 -3
  6. package/dist/src/config/agentClientLifecycle.js +27 -14
  7. package/dist/src/config/agentClientLifecycle.js.map +1 -1
  8. package/dist/src/config/config.d.ts +2 -5
  9. package/dist/src/config/config.js +10 -23
  10. package/dist/src/config/config.js.map +1 -1
  11. package/dist/src/config/configBase.d.ts +5 -1
  12. package/dist/src/config/configBase.js +27 -6
  13. package/dist/src/config/configBase.js.map +1 -1
  14. package/dist/src/config/configBaseCore.d.ts +26 -8
  15. package/dist/src/config/configBaseCore.js +30 -26
  16. package/dist/src/config/configBaseCore.js.map +1 -1
  17. package/dist/src/config/configMcpRuntime.d.ts +16 -0
  18. package/dist/src/config/configMcpRuntime.js +31 -0
  19. package/dist/src/config/configMcpRuntime.js.map +1 -0
  20. package/dist/src/config/configMediaDefaults.d.ts +10 -0
  21. package/dist/src/config/configMediaDefaults.js +17 -0
  22. package/dist/src/config/configMediaDefaults.js.map +1 -0
  23. package/dist/src/config/configTestHarness.d.ts +4 -0
  24. package/dist/src/config/configTypes.d.ts +4 -54
  25. package/dist/src/config/configTypes.js +6 -82
  26. package/dist/src/config/configTypes.js.map +1 -1
  27. package/dist/src/config/index.d.ts +1 -2
  28. package/dist/src/config/index.js +1 -2
  29. package/dist/src/config/index.js.map +1 -1
  30. package/dist/src/config/models.d.ts +0 -4
  31. package/dist/src/config/models.js +0 -4
  32. package/dist/src/config/models.js.map +1 -1
  33. package/dist/src/config/toolRegistryFactory.d.ts +2 -2
  34. package/dist/src/core/clientContract.d.ts +4 -6
  35. package/dist/src/core/compression/transcriptPathNotice.d.ts +22 -0
  36. package/dist/src/core/compression/transcriptPathNotice.js +29 -0
  37. package/dist/src/core/compression/transcriptPathNotice.js.map +1 -0
  38. package/dist/src/core/contentGenerator.d.ts +2 -5
  39. package/dist/src/core/contentGenerator.js +10 -24
  40. package/dist/src/core/contentGenerator.js.map +1 -1
  41. package/dist/src/core/logger.d.ts +66 -0
  42. package/dist/src/core/logger.js +345 -30
  43. package/dist/src/core/logger.js.map +1 -1
  44. package/dist/src/core/prompts.d.ts +0 -1
  45. package/dist/src/core/prompts.js +5 -79
  46. package/dist/src/core/prompts.js.map +1 -1
  47. package/dist/src/core/turn.d.ts +3 -3
  48. package/dist/src/hooks/hookTranslator.js +5 -4
  49. package/dist/src/hooks/hookTranslator.js.map +1 -1
  50. package/dist/src/index.d.ts +8 -6
  51. package/dist/src/index.js +8 -6
  52. package/dist/src/index.js.map +1 -1
  53. package/dist/src/llm-types/index.d.ts +1 -1
  54. package/dist/src/llm-types/modelEnvelope.d.ts +2 -1
  55. package/dist/src/llm-types/modelEnvelope.js +17 -1
  56. package/dist/src/llm-types/modelEnvelope.js.map +1 -1
  57. package/dist/src/models/schema.d.ts +40 -40
  58. package/dist/src/policy/policies/read-only.toml +0 -5
  59. package/dist/src/prompt-config/TemplateEngine.js +0 -3
  60. package/dist/src/prompt-config/TemplateEngine.js.map +1 -1
  61. package/dist/src/prompt-config/defaults/providers/gemini/core.md +0 -2
  62. package/dist/src/prompt-config/defaults/providers/gemini/models/gemini-2.5-flash/core.md +0 -2
  63. package/dist/src/prompt-config/defaults/providers/gemini/models/gemini-2.5-flash/gemini-2-5-flash/core.md +0 -2
  64. package/dist/src/prompt-config/prompt-loader.d.ts +1 -1
  65. package/dist/src/prompt-config/prompt-loader.js +4 -4
  66. package/dist/src/prompt-config/prompt-loader.js.map +1 -1
  67. package/dist/src/prompt-config/types.d.ts +0 -1
  68. package/dist/src/recording/CheckpointService.d.ts +4 -0
  69. package/dist/src/recording/CheckpointService.js +67 -46
  70. package/dist/src/recording/CheckpointService.js.map +1 -1
  71. package/dist/src/recording/HistoryMutationService.d.ts +1 -1
  72. package/dist/src/recording/HistoryMutationService.js +27 -4
  73. package/dist/src/recording/HistoryMutationService.js.map +1 -1
  74. package/dist/src/recording/RecordingIntegration.d.ts +36 -2
  75. package/dist/src/recording/RecordingIntegration.js +224 -7
  76. package/dist/src/recording/RecordingIntegration.js.map +1 -1
  77. package/dist/src/recording/ReplayEngine.d.ts +8 -10
  78. package/dist/src/recording/ReplayEngine.js +161 -95
  79. package/dist/src/recording/ReplayEngine.js.map +1 -1
  80. package/dist/src/recording/SessionDiscovery.d.ts +4 -2
  81. package/dist/src/recording/SessionDiscovery.js +13 -5
  82. package/dist/src/recording/SessionDiscovery.js.map +1 -1
  83. package/dist/src/recording/SessionRecordingService.d.ts +23 -3
  84. package/dist/src/recording/SessionRecordingService.js +209 -51
  85. package/dist/src/recording/SessionRecordingService.js.map +1 -1
  86. package/dist/src/recording/SessionTransitionService.d.ts +7 -0
  87. package/dist/src/recording/SessionTransitionService.js +66 -13
  88. package/dist/src/recording/SessionTransitionService.js.map +1 -1
  89. package/dist/src/recording/index.d.ts +1 -0
  90. package/dist/src/recording/index.js +1 -0
  91. package/dist/src/recording/index.js.map +1 -1
  92. package/dist/src/recording/janitor/cleanupTypes.d.ts +3 -0
  93. package/dist/src/recording/janitor/cleanupTypes.js.map +1 -1
  94. package/dist/src/recording/janitor/mediaReclamation.d.ts +23 -0
  95. package/dist/src/recording/janitor/mediaReclamation.js +195 -0
  96. package/dist/src/recording/janitor/mediaReclamation.js.map +1 -0
  97. package/dist/src/recording/janitor/sessionJanitor.js +47 -1
  98. package/dist/src/recording/janitor/sessionJanitor.js.map +1 -1
  99. package/dist/src/recording/janitor/sessionScanner.d.ts +12 -9
  100. package/dist/src/recording/janitor/sessionScanner.js +248 -193
  101. package/dist/src/recording/janitor/sessionScanner.js.map +1 -1
  102. package/dist/src/recording/replay-test-helpers.d.ts +10 -1
  103. package/dist/src/recording/replay-test-helpers.js +24 -2
  104. package/dist/src/recording/replay-test-helpers.js.map +1 -1
  105. package/dist/src/recording/replayCheckpointMetadata.d.ts +28 -0
  106. package/dist/src/recording/replayCheckpointMetadata.js +96 -0
  107. package/dist/src/recording/replayCheckpointMetadata.js.map +1 -0
  108. package/dist/src/recording/replayErrorFormatting.d.ts +6 -0
  109. package/dist/src/recording/replayErrorFormatting.js +38 -0
  110. package/dist/src/recording/replayErrorFormatting.js.map +1 -0
  111. package/dist/src/recording/resumeSession.d.ts +3 -0
  112. package/dist/src/recording/resumeSession.js +7 -1
  113. package/dist/src/recording/resumeSession.js.map +1 -1
  114. package/dist/src/recording/semanticMediaPurgeReplayValidation.d.ts +14 -0
  115. package/dist/src/recording/semanticMediaPurgeReplayValidation.js +24 -0
  116. package/dist/src/recording/semanticMediaPurgeReplayValidation.js.map +1 -0
  117. package/dist/src/recording/session-media-package-blobs.d.ts +8 -0
  118. package/dist/src/recording/session-media-package-blobs.js +72 -0
  119. package/dist/src/recording/session-media-package-blobs.js.map +1 -0
  120. package/dist/src/recording/session-media-package-import.d.ts +26 -0
  121. package/dist/src/recording/session-media-package-import.js +124 -0
  122. package/dist/src/recording/session-media-package-import.js.map +1 -0
  123. package/dist/src/recording/session-media-package-state.d.ts +19 -0
  124. package/dist/src/recording/session-media-package-state.js +56 -0
  125. package/dist/src/recording/session-media-package-state.js.map +1 -0
  126. package/dist/src/recording/session-media-package-validation.d.ts +59 -0
  127. package/dist/src/recording/session-media-package-validation.js +286 -0
  128. package/dist/src/recording/session-media-package-validation.js.map +1 -0
  129. package/dist/src/recording/session-media-package-writer.d.ts +18 -0
  130. package/dist/src/recording/session-media-package-writer.js +70 -0
  131. package/dist/src/recording/session-media-package-writer.js.map +1 -0
  132. package/dist/src/recording/session-media-package.d.ts +27 -0
  133. package/dist/src/recording/session-media-package.js +366 -0
  134. package/dist/src/recording/session-media-package.js.map +1 -0
  135. package/dist/src/recording/types.d.ts +34 -2
  136. package/dist/src/recording/types.js.map +1 -1
  137. package/dist/src/runtime/AgentRuntimeContext.d.ts +22 -5
  138. package/dist/src/runtime/AgentRuntimeLoader.d.ts +6 -0
  139. package/dist/src/runtime/AgentRuntimeLoader.js +25 -6
  140. package/dist/src/runtime/AgentRuntimeLoader.js.map +1 -1
  141. package/dist/src/runtime/contracts/PromptEstimation.d.ts +1 -0
  142. package/dist/src/runtime/contracts/PromptEstimation.js.map +1 -1
  143. package/dist/src/runtime/contracts/RuntimeProvider.d.ts +3 -2
  144. package/dist/src/runtime/contracts/RuntimeProviderManager.d.ts +0 -2
  145. package/dist/src/runtime/createAgentRuntimeContext.js +28 -1
  146. package/dist/src/runtime/createAgentRuntimeContext.js.map +1 -1
  147. package/dist/src/runtime/providerRuntimeContext.d.ts +12 -0
  148. package/dist/src/runtime/providerRuntimeContext.js +3 -0
  149. package/dist/src/runtime/providerRuntimeContext.js.map +1 -1
  150. package/dist/src/runtime/runtimeAdapters.js +2 -2
  151. package/dist/src/runtime/runtimeAdapters.js.map +1 -1
  152. package/dist/src/services/history/ContentConverters.d.ts +11 -7
  153. package/dist/src/services/history/ContentConverters.js +11 -7
  154. package/dist/src/services/history/ContentConverters.js.map +1 -1
  155. package/dist/src/services/history/HistoryService.d.ts +18 -180
  156. package/dist/src/services/history/HistoryService.js +53 -523
  157. package/dist/src/services/history/HistoryService.js.map +1 -1
  158. package/dist/src/services/history/HistoryServiceCore.d.ts +278 -0
  159. package/dist/src/services/history/HistoryServiceCore.js +727 -0
  160. package/dist/src/services/history/HistoryServiceCore.js.map +1 -0
  161. package/dist/src/services/history/IContent.d.ts +118 -16
  162. package/dist/src/services/history/IContent.js +284 -4
  163. package/dist/src/services/history/IContent.js.map +1 -1
  164. package/dist/src/services/history/contentSize.js +22 -2
  165. package/dist/src/services/history/contentSize.js.map +1 -1
  166. package/dist/src/services/history/historyChronology.d.ts +7 -0
  167. package/dist/src/services/history/historyChronology.js +35 -3
  168. package/dist/src/services/history/historyChronology.js.map +1 -1
  169. package/dist/src/services/history/historyCloneUtils.d.ts +5 -4
  170. package/dist/src/services/history/historyCloneUtils.js +23 -16
  171. package/dist/src/services/history/historyCloneUtils.js.map +1 -1
  172. package/dist/src/services/history/historyCompressionQueue.d.ts +33 -0
  173. package/dist/src/services/history/historyCompressionQueue.js +81 -0
  174. package/dist/src/services/history/historyCompressionQueue.js.map +1 -0
  175. package/dist/src/services/history/historyEventTypes.d.ts +3 -0
  176. package/dist/src/services/history/historyMutationFailure.d.ts +15 -0
  177. package/dist/src/services/history/historyMutationFailure.js +22 -0
  178. package/dist/src/services/history/historyMutationFailure.js.map +1 -1
  179. package/dist/src/services/history/historyProviderPipeline.d.ts +1 -1
  180. package/dist/src/services/history/historyProviderPipeline.js +15 -5
  181. package/dist/src/services/history/historyProviderPipeline.js.map +1 -1
  182. package/dist/src/services/history/historyTokenEstimation.js +10 -6
  183. package/dist/src/services/history/historyTokenEstimation.js.map +1 -1
  184. package/dist/src/services/history/historyToolNormalization.d.ts +2 -0
  185. package/dist/src/services/history/historyToolNormalization.js +26 -9
  186. package/dist/src/services/history/historyToolNormalization.js.map +1 -1
  187. package/dist/src/services/history/provider-file-binding.d.ts +11 -0
  188. package/dist/src/services/history/provider-file-binding.js +70 -0
  189. package/dist/src/services/history/provider-file-binding.js.map +1 -0
  190. package/dist/src/services/history/semantic-media-purge.d.ts +66 -0
  191. package/dist/src/services/history/semantic-media-purge.js +404 -0
  192. package/dist/src/services/history/semantic-media-purge.js.map +1 -0
  193. package/dist/src/storage/SessionPersistenceService.d.ts +53 -2
  194. package/dist/src/storage/SessionPersistenceService.js +435 -23
  195. package/dist/src/storage/SessionPersistenceService.js.map +1 -1
  196. package/dist/src/storage/history-media-ownership.d.ts +38 -0
  197. package/dist/src/storage/history-media-ownership.js +136 -0
  198. package/dist/src/storage/history-media-ownership.js.map +1 -0
  199. package/dist/src/storage/local-media-store-child.d.ts +6 -0
  200. package/dist/src/storage/local-media-store-child.js +140 -0
  201. package/dist/src/storage/local-media-store-child.js.map +1 -0
  202. package/dist/src/storage/local-media-store-files.d.ts +44 -0
  203. package/dist/src/storage/local-media-store-files.js +460 -0
  204. package/dist/src/storage/local-media-store-files.js.map +1 -0
  205. package/dist/src/storage/local-media-store-lock-recovery.d.ts +15 -0
  206. package/dist/src/storage/local-media-store-lock-recovery.js +112 -0
  207. package/dist/src/storage/local-media-store-lock-recovery.js.map +1 -0
  208. package/dist/src/storage/local-media-store-persistence.d.ts +48 -0
  209. package/dist/src/storage/local-media-store-persistence.js +443 -0
  210. package/dist/src/storage/local-media-store-persistence.js.map +1 -0
  211. package/dist/src/storage/local-media-store-quota.d.ts +6 -0
  212. package/dist/src/storage/local-media-store-quota.js +66 -0
  213. package/dist/src/storage/local-media-store-quota.js.map +1 -0
  214. package/dist/src/storage/local-media-store-reservations.d.ts +55 -0
  215. package/dist/src/storage/local-media-store-reservations.js +377 -0
  216. package/dist/src/storage/local-media-store-reservations.js.map +1 -0
  217. package/dist/src/storage/local-media-store-types.d.ts +110 -0
  218. package/dist/src/storage/local-media-store-types.js +35 -0
  219. package/dist/src/storage/local-media-store-types.js.map +1 -0
  220. package/dist/src/storage/local-media-store-validation.d.ts +34 -0
  221. package/dist/src/storage/local-media-store-validation.js +449 -0
  222. package/dist/src/storage/local-media-store-validation.js.map +1 -0
  223. package/dist/src/storage/local-media-store.d.ts +47 -0
  224. package/dist/src/storage/local-media-store.js +353 -0
  225. package/dist/src/storage/local-media-store.js.map +1 -0
  226. package/dist/src/storage/media-admission-service.d.ts +49 -0
  227. package/dist/src/storage/media-admission-service.js +333 -0
  228. package/dist/src/storage/media-admission-service.js.map +1 -0
  229. package/dist/src/storage/media-lifecycle-metrics.d.ts +75 -0
  230. package/dist/src/storage/media-lifecycle-metrics.js +105 -0
  231. package/dist/src/storage/media-lifecycle-metrics.js.map +1 -0
  232. package/dist/src/storage/media-reference-lifecycle.d.ts +16 -0
  233. package/dist/src/storage/media-reference-lifecycle.js +84 -0
  234. package/dist/src/storage/media-reference-lifecycle.js.map +1 -0
  235. package/dist/src/storage/request-media-resolver.d.ts +67 -0
  236. package/dist/src/storage/request-media-resolver.js +325 -0
  237. package/dist/src/storage/request-media-resolver.js.map +1 -0
  238. package/dist/src/storage/session-media-service-factories.d.ts +19 -0
  239. package/dist/src/storage/session-media-service-factories.js +34 -0
  240. package/dist/src/storage/session-media-service-factories.js.map +1 -0
  241. package/dist/src/storage/session-persistence-helpers.d.ts +10 -0
  242. package/dist/src/storage/session-persistence-helpers.js +46 -0
  243. package/dist/src/storage/session-persistence-helpers.js.map +1 -0
  244. package/dist/src/test-utils/config.d.ts +2 -0
  245. package/dist/src/test-utils/config.js +5 -5
  246. package/dist/src/test-utils/config.js.map +1 -1
  247. package/dist/src/test-utils/runtime.d.ts +2 -0
  248. package/dist/src/test-utils/runtime.js +1 -2
  249. package/dist/src/test-utils/runtime.js.map +1 -1
  250. package/dist/src/tools-adapters/CoreShellToolHostAdapter.js +1 -9
  251. package/dist/src/tools-adapters/CoreShellToolHostAdapter.js.map +1 -1
  252. package/dist/src/tools-adapters/CoreSkillServiceAdapter.d.ts +0 -2
  253. package/dist/src/tools-adapters/CoreSkillServiceAdapter.js +0 -17
  254. package/dist/src/tools-adapters/CoreSkillServiceAdapter.js.map +1 -1
  255. package/dist/src/tools-adapters/CoreToolHostAdapter.d.ts +0 -21
  256. package/dist/src/tools-adapters/CoreToolHostAdapter.js +0 -8
  257. package/dist/src/tools-adapters/CoreToolHostAdapter.js.map +1 -1
  258. package/dist/src/utils/environmentContext.d.ts +8 -9
  259. package/dist/src/utils/environmentContext.js +11 -22
  260. package/dist/src/utils/environmentContext.js.map +1 -1
  261. package/dist/src/utils/errorParsing.d.ts +1 -2
  262. package/dist/src/utils/errorParsing.js +22 -41
  263. package/dist/src/utils/errorParsing.js.map +1 -1
  264. package/dist/src/utils/generateContentResponseUtilities.js +12 -0
  265. package/dist/src/utils/generateContentResponseUtilities.js.map +1 -1
  266. package/dist/src/utils/summarizer.d.ts +1 -2
  267. package/dist/src/utils/summarizer.js +6 -5
  268. package/dist/src/utils/summarizer.js.map +1 -1
  269. package/dist/src/utils/tool-utils.js +7 -1
  270. package/dist/src/utils/tool-utils.js.map +1 -1
  271. package/index.ts +0 -4
  272. package/package.json +38 -30
  273. package/src/config/agentClientLifecycle.ts +53 -22
  274. package/src/config/config.ts +11 -26
  275. package/src/config/configBase.ts +46 -7
  276. package/src/config/configBaseCore.ts +38 -36
  277. package/src/config/configMcpRuntime.ts +46 -0
  278. package/src/config/configMediaDefaults.ts +19 -0
  279. package/src/config/configTypes.ts +13 -53
  280. package/src/config/index.ts +1 -4
  281. package/src/config/models.ts +0 -6
  282. package/src/config/toolRegistryFactory.ts +2 -2
  283. package/src/core/clientContract.ts +4 -6
  284. package/src/core/compression/transcriptPathNotice.ts +31 -0
  285. package/src/core/contentGenerator.ts +15 -39
  286. package/src/core/logger.ts +370 -39
  287. package/src/core/prompts.ts +4 -114
  288. package/src/core/turn.ts +3 -3
  289. package/src/hooks/hookTranslator.ts +6 -4
  290. package/src/index.ts +7 -7
  291. package/src/llm-types/index.ts +5 -0
  292. package/src/llm-types/modelEnvelope.ts +26 -2
  293. package/src/policy/policies/read-only.toml +0 -5
  294. package/src/prompt-config/TemplateEngine.ts +0 -3
  295. package/src/prompt-config/defaults/providers/gemini/core.md +0 -2
  296. package/src/prompt-config/defaults/providers/gemini/models/gemini-2.5-flash/core.md +0 -2
  297. package/src/prompt-config/defaults/providers/gemini/models/gemini-2.5-flash/gemini-2-5-flash/core.md +0 -2
  298. package/src/prompt-config/prompt-loader.ts +7 -8
  299. package/src/prompt-config/types.ts +0 -1
  300. package/src/recording/CheckpointService.ts +110 -45
  301. package/src/recording/HistoryMutationService.ts +28 -3
  302. package/src/recording/RecordingIntegration.ts +258 -11
  303. package/src/recording/ReplayEngine.ts +220 -110
  304. package/src/recording/SessionDiscovery.ts +30 -4
  305. package/src/recording/SessionRecordingService.ts +253 -55
  306. package/src/recording/SessionTransitionService.ts +75 -12
  307. package/src/recording/index.ts +7 -0
  308. package/src/recording/janitor/cleanupTypes.ts +4 -0
  309. package/src/recording/janitor/mediaReclamation.ts +295 -0
  310. package/src/recording/janitor/sessionJanitor.ts +54 -1
  311. package/src/recording/janitor/sessionScanner.ts +319 -227
  312. package/src/recording/replay-test-helpers.ts +33 -2
  313. package/src/recording/replayCheckpointMetadata.ts +115 -0
  314. package/src/recording/replayErrorFormatting.ts +43 -0
  315. package/src/recording/resumeSession.ts +10 -0
  316. package/src/recording/semanticMediaPurgeReplayValidation.ts +35 -0
  317. package/src/recording/session-media-package-blobs.ts +116 -0
  318. package/src/recording/session-media-package-import.ts +189 -0
  319. package/src/recording/session-media-package-state.ts +120 -0
  320. package/src/recording/session-media-package-validation.ts +400 -0
  321. package/src/recording/session-media-package-writer.ts +117 -0
  322. package/src/recording/session-media-package.ts +692 -0
  323. package/src/recording/types.ts +37 -2
  324. package/src/runtime/AgentRuntimeContext.ts +28 -5
  325. package/src/runtime/AgentRuntimeLoader.ts +32 -7
  326. package/src/runtime/contracts/PromptEstimation.ts +1 -0
  327. package/src/runtime/contracts/RuntimeProvider.ts +3 -8
  328. package/src/runtime/contracts/RuntimeProviderManager.ts +0 -2
  329. package/src/runtime/createAgentRuntimeContext.ts +43 -1
  330. package/src/runtime/providerRuntimeContext.ts +22 -0
  331. package/src/runtime/runtimeAdapters.ts +2 -2
  332. package/src/services/history/ContentConverters.ts +11 -7
  333. package/src/services/history/HistoryService.ts +71 -696
  334. package/src/services/history/HistoryServiceCore.ts +1055 -0
  335. package/src/services/history/IContent.ts +460 -20
  336. package/src/services/history/contentSize.ts +22 -2
  337. package/src/services/history/historyChronology.ts +53 -3
  338. package/src/services/history/historyCloneUtils.ts +26 -22
  339. package/src/services/history/historyCompressionQueue.ts +102 -0
  340. package/src/services/history/historyEventTypes.ts +9 -0
  341. package/src/services/history/historyMutationFailure.ts +33 -0
  342. package/src/services/history/historyProviderPipeline.ts +19 -5
  343. package/src/services/history/historyTokenEstimation.ts +9 -5
  344. package/src/services/history/historyToolNormalization.ts +43 -11
  345. package/src/services/history/provider-file-binding.ts +115 -0
  346. package/src/services/history/semantic-media-purge.ts +593 -0
  347. package/src/storage/SessionPersistenceService.ts +667 -30
  348. package/src/storage/history-media-ownership.ts +185 -0
  349. package/src/storage/local-media-store-child.ts +163 -0
  350. package/src/storage/local-media-store-files.ts +643 -0
  351. package/src/storage/local-media-store-lock-recovery.ts +159 -0
  352. package/src/storage/local-media-store-persistence.ts +737 -0
  353. package/src/storage/local-media-store-quota.ts +111 -0
  354. package/src/storage/local-media-store-reservations.ts +485 -0
  355. package/src/storage/local-media-store-types.ts +161 -0
  356. package/src/storage/local-media-store-validation.ts +643 -0
  357. package/src/storage/local-media-store.ts +696 -0
  358. package/src/storage/media-admission-service.ts +512 -0
  359. package/src/storage/media-lifecycle-metrics.ts +228 -0
  360. package/src/storage/media-reference-lifecycle.ts +164 -0
  361. package/src/storage/request-media-resolver.ts +491 -0
  362. package/src/storage/session-media-service-factories.ts +48 -0
  363. package/src/storage/session-persistence-helpers.ts +85 -0
  364. package/src/test-utils/config.ts +7 -5
  365. package/src/test-utils/runtime.ts +3 -2
  366. package/src/tools-adapters/CoreShellToolHostAdapter.ts +1 -11
  367. package/src/tools-adapters/CoreSkillServiceAdapter.ts +0 -23
  368. package/src/tools-adapters/CoreToolHostAdapter.ts +0 -36
  369. package/src/utils/environmentContext.ts +11 -30
  370. package/src/utils/errorParsing.ts +19 -69
  371. package/src/utils/generateContentResponseUtilities.ts +28 -1
  372. package/src/utils/summarizer.ts +8 -10
  373. package/src/utils/tool-utils.ts +7 -1
  374. package/dist/src/code_assist/codeAssist.d.ts +0 -19
  375. package/dist/src/code_assist/codeAssist.js +0 -41
  376. package/dist/src/code_assist/codeAssist.js.map +0 -1
  377. package/dist/src/code_assist/contentGeneratorAdapters.d.ts +0 -49
  378. package/dist/src/code_assist/contentGeneratorAdapters.js +0 -197
  379. package/dist/src/code_assist/contentGeneratorAdapters.js.map +0 -1
  380. package/dist/src/code_assist/converter.d.ts +0 -74
  381. package/dist/src/code_assist/converter.js +0 -158
  382. package/dist/src/code_assist/converter.js.map +0 -1
  383. package/dist/src/code_assist/googleGenAIWrapper.d.ts +0 -27
  384. package/dist/src/code_assist/googleGenAIWrapper.js +0 -46
  385. package/dist/src/code_assist/googleGenAIWrapper.js.map +0 -1
  386. package/dist/src/code_assist/oauth-credential-storage.d.ts +0 -30
  387. package/dist/src/code_assist/oauth-credential-storage.js +0 -135
  388. package/dist/src/code_assist/oauth-credential-storage.js.map +0 -1
  389. package/dist/src/code_assist/server.d.ts +0 -44
  390. package/dist/src/code_assist/server.js +0 -154
  391. package/dist/src/code_assist/server.js.map +0 -1
  392. package/dist/src/code_assist/setup.d.ts +0 -20
  393. package/dist/src/code_assist/setup.js +0 -126
  394. package/dist/src/code_assist/setup.js.map +0 -1
  395. package/dist/src/code_assist/types.d.ts +0 -161
  396. package/dist/src/code_assist/types.js +0 -46
  397. package/dist/src/code_assist/types.js.map +0 -1
  398. package/dist/src/utils/getFolderStructure.d.ts +0 -31
  399. package/dist/src/utils/getFolderStructure.js +0 -240
  400. package/dist/src/utils/getFolderStructure.js.map +0 -1
  401. package/dist/src/utils/installationManager.d.ts +0 -16
  402. package/dist/src/utils/installationManager.js +0 -51
  403. package/dist/src/utils/installationManager.js.map +0 -1
  404. package/dist/src/utils/llm-edit-fixer.d.ts +0 -25
  405. package/dist/src/utils/llm-edit-fixer.js +0 -120
  406. package/dist/src/utils/llm-edit-fixer.js.map +0 -1
  407. package/src/code_assist/codeAssist.ts +0 -59
  408. package/src/code_assist/contentGeneratorAdapters.ts +0 -275
  409. package/src/code_assist/converter.ts +0 -288
  410. package/src/code_assist/googleGenAIWrapper.ts +0 -90
  411. package/src/code_assist/oauth-credential-storage.ts +0 -171
  412. package/src/code_assist/server.ts +0 -263
  413. package/src/code_assist/setup.ts +0 -189
  414. package/src/code_assist/types.ts +0 -201
  415. package/src/utils/getFolderStructure.ts +0 -382
  416. package/src/utils/installationManager.ts +0 -59
  417. package/src/utils/llm-edit-fixer.ts +0 -157
@@ -0,0 +1,491 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { randomUUID } from 'node:crypto';
8
+ import {
9
+ isMediaReferenceBlock,
10
+ type IContent,
11
+ type InlineMediaBlock,
12
+ type MediaReferenceBlock,
13
+ } from '../services/history/IContent.js';
14
+ import type { LocalMediaStore } from './local-media-store.js';
15
+ import { DEFAULT_IMAGE_PAYLOAD_BUDGET_BYTES } from '../config/configTypes.js';
16
+
17
+ export const DEFAULT_REQUEST_MEDIA_BUDGET_BYTES =
18
+ DEFAULT_IMAGE_PAYLOAD_BUDGET_BYTES;
19
+
20
+ export interface RequestMediaResolutionInput {
21
+ readonly contents: readonly IContent[];
22
+ readonly requestId: string;
23
+ readonly turnId: string;
24
+ readonly aggregateBudgetBytes: number;
25
+ readonly signal?: AbortSignal;
26
+ }
27
+
28
+ export interface RequestMediaAccounting {
29
+ readonly selectedReferenceCount: number;
30
+ readonly uniqueContentCount: number;
31
+ readonly selectedNormalizedBytes: number;
32
+ readonly materializedNormalizedBytes: number;
33
+ readonly storeReadCount: number;
34
+ readonly reservedContentCount: number;
35
+ readonly released: boolean;
36
+ }
37
+
38
+ export interface RequestMediaResolverAccounting {
39
+ readonly activeRequestCount: number;
40
+ readonly reservedContentCount: number;
41
+ readonly materializedNormalizedBytes: number;
42
+ readonly storeReadCount: number;
43
+ }
44
+
45
+ export interface PendingMediaReleaseRecovery {
46
+ readonly attempted: number;
47
+ readonly recovered: number;
48
+ readonly remaining: number;
49
+ }
50
+
51
+ export interface ResolvedMediaRequest {
52
+ withContents<T>(consume: (contents: IContent[]) => T): T;
53
+ registerCleanup(cleanup: () => void | Promise<void>): void;
54
+ accounting(): RequestMediaAccounting;
55
+ release(): Promise<void>;
56
+ }
57
+
58
+ export interface RequestMediaResolutionService {
59
+ resolve(input: RequestMediaResolutionInput): Promise<ResolvedMediaRequest>;
60
+ }
61
+
62
+ interface SelectedReference {
63
+ readonly reference: MediaReferenceBlock;
64
+ readonly turnId: string;
65
+ }
66
+
67
+ export class RequestMediaResolutionError extends Error {
68
+ constructor(
69
+ readonly contentId: string,
70
+ readonly turnId: string,
71
+ operation: string,
72
+ options?: ErrorOptions,
73
+ ) {
74
+ super(
75
+ `Media request ${operation} failed for content ${contentId} in turn ${turnId}`,
76
+ options,
77
+ );
78
+ this.name = 'RequestMediaResolutionError';
79
+ }
80
+ }
81
+
82
+ function abortError(): Error {
83
+ const error = new Error('Media request resolution was aborted');
84
+ error.name = 'AbortError';
85
+ return error;
86
+ }
87
+
88
+ function throwIfAborted(signal: AbortSignal | undefined): void {
89
+ if (signal?.aborted === true) throw abortError();
90
+ }
91
+
92
+ function validateBudget(budget: number): void {
93
+ if (!Number.isSafeInteger(budget) || budget < 0) {
94
+ throw new Error(
95
+ 'Aggregate request media budget must be a non-negative safe integer',
96
+ );
97
+ }
98
+ }
99
+
100
+ function contentTurnId(content: IContent, fallbackTurnId: string): string {
101
+ return (
102
+ content.metadata?.turnId ??
103
+ content.metadata?.id ??
104
+ (content.metadata?.chronology === undefined
105
+ ? fallbackTurnId
106
+ : `chronology:${content.metadata.chronology.seq}`)
107
+ );
108
+ }
109
+
110
+ function selectReferences(
111
+ input: RequestMediaResolutionInput,
112
+ ): readonly SelectedReference[] {
113
+ const selected: SelectedReference[] = [];
114
+ for (const content of input.contents) {
115
+ const turnId = contentTurnId(content, input.turnId);
116
+ for (const block of content.blocks) {
117
+ if (block.type !== 'media' || block.encoding !== 'reference') continue;
118
+ const candidate: unknown = block;
119
+ if (!isMediaReferenceBlock(candidate)) {
120
+ throw new RequestMediaResolutionError(
121
+ block.contentId,
122
+ turnId,
123
+ 'metadata validation',
124
+ );
125
+ }
126
+ selected.push({ reference: candidate, turnId });
127
+ }
128
+ }
129
+ return selected;
130
+ }
131
+
132
+ function selectedNormalizedBytes(input: RequestMediaResolutionInput): number {
133
+ let total = 0;
134
+ for (const content of input.contents) {
135
+ const turnId = contentTurnId(content, input.turnId);
136
+ for (const block of content.blocks) {
137
+ if (block.type !== 'media' || block.encoding === 'url') continue;
138
+ const normalizedLength =
139
+ block.encoding === 'reference'
140
+ ? block.normalizedBase64Length
141
+ : block.data.length;
142
+ const nextTotal = total + normalizedLength;
143
+ if (
144
+ !Number.isSafeInteger(nextTotal) ||
145
+ nextTotal > input.aggregateBudgetBytes
146
+ ) {
147
+ throw new RequestMediaResolutionError(
148
+ block.encoding === 'reference' ? block.contentId : 'inline-media',
149
+ turnId,
150
+ `aggregate budget (${nextTotal} > ${input.aggregateBudgetBytes})`,
151
+ );
152
+ }
153
+ total = nextTotal;
154
+ }
155
+ }
156
+ return total;
157
+ }
158
+
159
+ export function assertRequestMediaBudget(
160
+ contents: readonly IContent[],
161
+ turnId: string,
162
+ aggregateBudgetBytes: number,
163
+ ): void {
164
+ validateBudget(aggregateBudgetBytes);
165
+ selectedNormalizedBytes({
166
+ contents,
167
+ requestId: 'request-media-budget-validation',
168
+ turnId,
169
+ aggregateBudgetBytes,
170
+ });
171
+ }
172
+
173
+ function inlineBlock(
174
+ reference: MediaReferenceBlock,
175
+ data: string,
176
+ ): InlineMediaBlock {
177
+ const block: InlineMediaBlock = {
178
+ type: 'media',
179
+ encoding: 'base64',
180
+ data,
181
+ mimeType: reference.mimeType,
182
+ ...(reference.caption === undefined ? {} : { caption: reference.caption }),
183
+ ...(reference.filename === undefined
184
+ ? {}
185
+ : { filename: reference.filename }),
186
+ ...(reference.providerMetadata === undefined
187
+ ? {}
188
+ : { providerMetadata: reference.providerMetadata }),
189
+ ...(reference.dimensions === undefined
190
+ ? {}
191
+ : { dimensions: reference.dimensions }),
192
+ semanticMetadata: reference.semanticMetadata,
193
+ ...(reference.providerFileIds === undefined
194
+ ? {}
195
+ : { providerFileIds: reference.providerFileIds }),
196
+ ...(reference.providerFiles === undefined
197
+ ? {}
198
+ : { providerFiles: reference.providerFiles }),
199
+ };
200
+ Object.defineProperty(block, 'sourceContentId', {
201
+ value: reference.contentId,
202
+ enumerable: false,
203
+ configurable: false,
204
+ writable: false,
205
+ });
206
+ return block;
207
+ }
208
+
209
+ function materializeContents(
210
+ contents: readonly IContent[],
211
+ encodedByContentId: ReadonlyMap<string, string>,
212
+ ): IContent[] {
213
+ return contents.map((content) => {
214
+ const blocks = content.blocks.map((block) => {
215
+ if (block.type !== 'media' || block.encoding !== 'reference')
216
+ return block;
217
+ const data = encodedByContentId.get(block.contentId);
218
+ if (data === undefined) {
219
+ throw new RequestMediaResolutionError(
220
+ block.contentId,
221
+ contentTurnId(content, 'unknown'),
222
+ 'materialization',
223
+ );
224
+ }
225
+ return inlineBlock(block, data);
226
+ });
227
+ const changed = blocks.some(
228
+ (block, index) => block !== content.blocks[index],
229
+ );
230
+ return changed ? { ...content, blocks } : content;
231
+ });
232
+ }
233
+
234
+ interface RequestResolutionResources {
235
+ readonly ownerId: string;
236
+ readonly reservedContentIds: string[];
237
+ readonly encodedByContentId: Map<string, string>;
238
+ readonly registeredCleanups: Array<() => void | Promise<void>>;
239
+ resolvedContents: IContent[];
240
+ materializedBytes: number;
241
+ readCount: number;
242
+ disposed: boolean;
243
+ released: boolean;
244
+ releasePromise: Promise<void> | undefined;
245
+ }
246
+
247
+ function uniqueReferencesByContentId(
248
+ selected: readonly SelectedReference[],
249
+ ): ReadonlyMap<string, SelectedReference> {
250
+ const unique = new Map<string, SelectedReference>();
251
+ for (const entry of selected) {
252
+ if (!unique.has(entry.reference.contentId)) {
253
+ unique.set(entry.reference.contentId, entry);
254
+ }
255
+ }
256
+ return unique;
257
+ }
258
+
259
+ export class RequestMediaResolver {
260
+ private activeRequestCount = 0;
261
+ private reservedContentCount = 0;
262
+ private materializedNormalizedBytes = 0;
263
+ private storeReadCount = 0;
264
+ private readonly pendingReleases = new Set<RequestResolutionResources>();
265
+
266
+ constructor(private readonly store: LocalMediaStore) {}
267
+
268
+ accounting(): RequestMediaResolverAccounting {
269
+ return {
270
+ activeRequestCount: this.activeRequestCount,
271
+ reservedContentCount: this.reservedContentCount,
272
+ materializedNormalizedBytes: this.materializedNormalizedBytes,
273
+ storeReadCount: this.storeReadCount,
274
+ };
275
+ }
276
+
277
+ pendingReleaseCount(): number {
278
+ return this.pendingReleases.size;
279
+ }
280
+
281
+ async recoverPendingReleases(): Promise<PendingMediaReleaseRecovery> {
282
+ const pending = [...this.pendingReleases];
283
+ const failures: unknown[] = [];
284
+ let recovered = 0;
285
+ for (const resources of pending) {
286
+ try {
287
+ await this.release(resources);
288
+ recovered += 1;
289
+ } catch (error) {
290
+ failures.push(error);
291
+ }
292
+ }
293
+ const result = {
294
+ attempted: pending.length,
295
+ recovered,
296
+ remaining: this.pendingReleases.size,
297
+ };
298
+ if (failures.length > 0) {
299
+ throw new AggregateError(
300
+ failures,
301
+ 'Pending media release recovery failed',
302
+ {
303
+ cause: result,
304
+ },
305
+ );
306
+ }
307
+ return result;
308
+ }
309
+
310
+ private async dispose(resources: RequestResolutionResources): Promise<void> {
311
+ const failures: unknown[] = [];
312
+ if (!resources.disposed) {
313
+ resources.disposed = true;
314
+ for (
315
+ let index = resources.registeredCleanups.length - 1;
316
+ index >= 0;
317
+ index -= 1
318
+ ) {
319
+ try {
320
+ await resources.registeredCleanups[index]();
321
+ } catch (error) {
322
+ failures.push(error);
323
+ }
324
+ }
325
+ resources.registeredCleanups.splice(0);
326
+ resources.resolvedContents.splice(0);
327
+ resources.encodedByContentId.clear();
328
+ this.materializedNormalizedBytes -= resources.materializedBytes;
329
+ resources.materializedBytes = 0;
330
+ }
331
+ let releasedReservationCount = 0;
332
+ for (
333
+ let index = resources.reservedContentIds.length - 1;
334
+ index >= 0;
335
+ index -= 1
336
+ ) {
337
+ try {
338
+ await this.store.release(
339
+ resources.reservedContentIds[index],
340
+ resources.ownerId,
341
+ );
342
+ resources.reservedContentIds.splice(index, 1);
343
+ releasedReservationCount += 1;
344
+ } catch (error) {
345
+ failures.push(error);
346
+ }
347
+ }
348
+ this.reservedContentCount -= releasedReservationCount;
349
+ if (resources.reservedContentIds.length === 0) {
350
+ this.activeRequestCount -= 1;
351
+ resources.released = true;
352
+ this.pendingReleases.delete(resources);
353
+ } else {
354
+ this.pendingReleases.add(resources);
355
+ }
356
+ if (failures.length > 0) {
357
+ throw new AggregateError(failures, 'Failed to release media request');
358
+ }
359
+ }
360
+
361
+ private release(resources: RequestResolutionResources): Promise<void> {
362
+ if (resources.released) return Promise.resolve();
363
+ resources.releasePromise ??= this.dispose(resources).finally(() => {
364
+ if (!resources.released) resources.releasePromise = undefined;
365
+ });
366
+ return resources.releasePromise;
367
+ }
368
+
369
+ private async materializeReferences(
370
+ input: RequestMediaResolutionInput,
371
+ unique: ReadonlyMap<string, SelectedReference>,
372
+ resources: RequestResolutionResources,
373
+ ): Promise<void> {
374
+ for (const entry of unique.values()) {
375
+ throwIfAborted(input.signal);
376
+ this.storeReadCount += 1;
377
+ resources.readCount += 1;
378
+ let bytes: Uint8Array;
379
+ try {
380
+ bytes = await this.store.reserveAndReadVerified(
381
+ entry.reference,
382
+ resources.ownerId,
383
+ );
384
+ } catch (error) {
385
+ throw new RequestMediaResolutionError(
386
+ entry.reference.contentId,
387
+ entry.turnId,
388
+ 'blob verification',
389
+ { cause: error },
390
+ );
391
+ }
392
+ resources.reservedContentIds.push(entry.reference.contentId);
393
+ this.reservedContentCount += 1;
394
+ throwIfAborted(input.signal);
395
+ const encoded = Buffer.from(bytes).toString('base64');
396
+ if (encoded.length !== entry.reference.normalizedBase64Length) {
397
+ throw new RequestMediaResolutionError(
398
+ entry.reference.contentId,
399
+ entry.turnId,
400
+ 'normalized size verification',
401
+ );
402
+ }
403
+ resources.encodedByContentId.set(entry.reference.contentId, encoded);
404
+ resources.materializedBytes += encoded.length;
405
+ this.materializedNormalizedBytes += encoded.length;
406
+ }
407
+ }
408
+
409
+ private resolvedRequest(
410
+ selectedReferenceCount: number,
411
+ uniqueContentCount: number,
412
+ selectedBytes: number,
413
+ resources: RequestResolutionResources,
414
+ ): ResolvedMediaRequest {
415
+ return {
416
+ withContents: <T>(consume: (contents: IContent[]) => T): T => {
417
+ if (resources.disposed) {
418
+ throw new Error(
419
+ 'Cannot consume media request contents after release',
420
+ );
421
+ }
422
+ return consume(resources.resolvedContents);
423
+ },
424
+ registerCleanup: (cleanup: () => void | Promise<void>): void => {
425
+ if (resources.disposed) {
426
+ throw new Error(
427
+ 'Cannot register materialized request cleanup after disposal',
428
+ );
429
+ }
430
+ resources.registeredCleanups.push(cleanup);
431
+ },
432
+ accounting: (): RequestMediaAccounting => ({
433
+ selectedReferenceCount,
434
+ uniqueContentCount,
435
+ selectedNormalizedBytes: selectedBytes,
436
+ materializedNormalizedBytes: resources.materializedBytes,
437
+ storeReadCount: resources.readCount,
438
+ reservedContentCount: resources.reservedContentIds.length,
439
+ released: resources.released,
440
+ }),
441
+ release: () => this.release(resources),
442
+ };
443
+ }
444
+
445
+ async resolve(
446
+ input: RequestMediaResolutionInput,
447
+ ): Promise<ResolvedMediaRequest> {
448
+ validateBudget(input.aggregateBudgetBytes);
449
+ throwIfAborted(input.signal);
450
+ const selected = selectReferences(input);
451
+ const selectedBytes = selectedNormalizedBytes(input);
452
+ throwIfAborted(input.signal);
453
+ const unique = uniqueReferencesByContentId(selected);
454
+ const resources: RequestResolutionResources = {
455
+ ownerId: `${input.requestId}:${randomUUID()}`,
456
+ reservedContentIds: [],
457
+ encodedByContentId: new Map(),
458
+ registeredCleanups: [],
459
+ resolvedContents: [],
460
+ materializedBytes: 0,
461
+ readCount: 0,
462
+ disposed: false,
463
+ released: false,
464
+ releasePromise: undefined,
465
+ };
466
+ this.activeRequestCount += 1;
467
+ try {
468
+ await this.materializeReferences(input, unique, resources);
469
+ resources.resolvedContents = materializeContents(
470
+ input.contents,
471
+ resources.encodedByContentId,
472
+ );
473
+ return this.resolvedRequest(
474
+ selected.length,
475
+ unique.size,
476
+ selectedBytes,
477
+ resources,
478
+ );
479
+ } catch (error) {
480
+ try {
481
+ await this.release(resources);
482
+ } catch (releaseError) {
483
+ throw new AggregateError(
484
+ [error, releaseError],
485
+ 'Media request resolution and cleanup failed',
486
+ );
487
+ }
488
+ throw error;
489
+ }
490
+ }
491
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import type { Storage } from '@vybestack/llxprt-code-settings';
8
+ import { join } from 'node:path';
9
+ import { LocalMediaStore } from './local-media-store.js';
10
+ import { SessionPersistenceService } from './SessionPersistenceService.js';
11
+
12
+ interface SessionMediaServiceHost {
13
+ readonly storage: Storage;
14
+ getMediaStoreQuotaByteLimit(): number;
15
+ getSessionPersistenceQueueByteLimit(): number;
16
+ }
17
+
18
+ interface SessionMediaServices {
19
+ readonly store: () => LocalMediaStore;
20
+ readonly persistence: (sessionId: string) => SessionPersistenceService;
21
+ }
22
+
23
+ export function sessionMediaServices(
24
+ host: SessionMediaServiceHost,
25
+ ): SessionMediaServices {
26
+ let mediaStore: LocalMediaStore | undefined;
27
+ const persistenceServices = new Map<string, SessionPersistenceService>();
28
+ const store = (): LocalMediaStore => {
29
+ mediaStore ??= new LocalMediaStore({
30
+ rootDirectory: join(host.storage.getProjectTempDir(), 'media'),
31
+ quotaBytes: host.getMediaStoreQuotaByteLimit(),
32
+ });
33
+ return mediaStore;
34
+ };
35
+ return {
36
+ store,
37
+ persistence: (sessionId) => {
38
+ const existing = persistenceServices.get(sessionId);
39
+ if (existing !== undefined) return existing;
40
+ const service = new SessionPersistenceService(host.storage, sessionId, {
41
+ mediaStore: store(),
42
+ maxQueueBytes: host.getSessionPersistenceQueueByteLimit(),
43
+ });
44
+ persistenceServices.set(sessionId, service);
45
+ return service;
46
+ },
47
+ };
48
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import type { IContent } from '../services/history/IContent.js';
8
+ import { MediaAdmissionError } from './media-admission-service.js';
9
+ import { MediaReferenceValidationError } from './media-reference-lifecycle.js';
10
+ import type {
11
+ PersistedSession,
12
+ PersistedUIHistoryItem,
13
+ } from './SessionPersistenceService.js';
14
+
15
+ const MAX_MEDIA_DIAGNOSTIC_DEPTH = 32;
16
+
17
+ function isUnknownArray(value: unknown): value is unknown[] {
18
+ return Array.isArray(value);
19
+ }
20
+
21
+ export function errorCode(error: unknown): unknown {
22
+ return typeof error === 'object' && error !== null
23
+ ? Reflect.get(error, 'code')
24
+ : undefined;
25
+ }
26
+
27
+ export function containsMediaDiagnostic(
28
+ error: unknown,
29
+ seen: Set<object> = new Set<object>(),
30
+ depth = 0,
31
+ ): boolean {
32
+ if (
33
+ error instanceof MediaReferenceValidationError ||
34
+ error instanceof MediaAdmissionError
35
+ ) {
36
+ return true;
37
+ }
38
+ if (
39
+ depth >= MAX_MEDIA_DIAGNOSTIC_DEPTH ||
40
+ typeof error !== 'object' ||
41
+ error === null ||
42
+ seen.has(error)
43
+ ) {
44
+ return false;
45
+ }
46
+ seen.add(error);
47
+ const nested = Reflect.get(error, 'errors');
48
+ return (
49
+ (isUnknownArray(nested) &&
50
+ nested.some((entry) =>
51
+ containsMediaDiagnostic(entry, seen, depth + 1),
52
+ )) ||
53
+ containsMediaDiagnostic(Reflect.get(error, 'cause'), seen, depth + 1)
54
+ );
55
+ }
56
+
57
+ function serializedStringContentLowerBound(
58
+ value: unknown,
59
+ visited: Set<object>,
60
+ ): number {
61
+ if (typeof value === 'string') return Buffer.byteLength(value, 'utf8');
62
+ if (typeof value !== 'object' || value === null || visited.has(value)) {
63
+ return 0;
64
+ }
65
+ visited.add(value);
66
+ return Object.values(value).reduce(
67
+ (bytes, nested) =>
68
+ Math.min(
69
+ Number.MAX_SAFE_INTEGER,
70
+ bytes + serializedStringContentLowerBound(nested, visited),
71
+ ),
72
+ 0,
73
+ );
74
+ }
75
+
76
+ export function persistenceRequestLowerBound(
77
+ history: readonly IContent[],
78
+ metadata: PersistedSession['metadata'] | undefined,
79
+ uiHistory: readonly PersistedUIHistoryItem[] | undefined,
80
+ ): number {
81
+ return serializedStringContentLowerBound(
82
+ [history, metadata, uiHistory],
83
+ new Set<object>(),
84
+ );
85
+ }
@@ -48,7 +48,7 @@ function createTestAgentChat(): AgentChatContract {
48
48
  sendMessageStream: async () => emptyChatStream(),
49
49
  generateDirectMessage: async () => emptyModelOutput(),
50
50
  getHistory: () => [],
51
- setHistory: () => {},
51
+ setHistory: async () => {},
52
52
  clearHistory: () => {},
53
53
  getHistoryService: () => null,
54
54
  wasRecentlyCompressed: () => false,
@@ -57,7 +57,9 @@ function createTestAgentChat(): AgentChatContract {
57
57
  };
58
58
  }
59
59
 
60
- function createTestAgentClient(): AgentClientContract {
60
+ export function createTestAgentClient(
61
+ overrides?: Partial<AgentClientContract>,
62
+ ): AgentClientContract {
61
63
  const chat = createTestAgentChat();
62
64
  return {
63
65
  initialize: async () => {},
@@ -67,8 +69,8 @@ function createTestAgentClient(): AgentClientContract {
67
69
  getHistory: async () => [],
68
70
  getHistoryService: () => null,
69
71
  storeHistoryServiceForReuse: () => {},
70
- storeHistoryForLaterUse: () => {},
71
- dispose: () => {},
72
+ storeHistoryForLaterUse: async () => {},
73
+ dispose: async () => {},
72
74
  setTools: async () => {},
73
75
  clearTools: () => {},
74
76
  updateSystemInstruction: async () => {},
@@ -85,8 +87,8 @@ function createTestAgentClient(): AgentClientContract {
85
87
  generateContent: async () => emptyModelOutput(),
86
88
  generateEmbedding: async (texts: string[]) => texts.map(() => []),
87
89
  sendMessageStream: () => emptyServerAgentStream(),
88
- getUserTier: () => undefined,
89
90
  getCurrentSequenceModel: () => null,
91
+ ...overrides,
90
92
  };
91
93
  }
92
94
 
@@ -8,6 +8,7 @@ import type { Config } from '../config/config.js';
8
8
  import type { RuntimeProvider as IProvider } from '../runtime/contracts/RuntimeProvider.js';
9
9
  import type { RuntimeProviderManager } from '../runtime/contracts/RuntimeProviderManager.js';
10
10
  import type { RuntimeTokenizerFactory } from '../runtime/contracts/RuntimeTokenizerFactory.js';
11
+ import type { SessionRecordingService } from '../recording/SessionRecordingService.js';
11
12
  // Type-only import of bun:test: erased at compile time, creates no runtime edge.
12
13
  // Required to obtain the precise `vi.fn()` Mock<T> return type.
13
14
  import type { vi as ViNamespace } from 'bun:test';
@@ -246,6 +247,7 @@ interface ChatSessionConfigShape {
246
247
  getProviderManager: ReturnType<ReturnType<typeof requireVi>['fn']>;
247
248
  getSettingsService: ReturnType<ReturnType<typeof requireVi>['fn']>;
248
249
  getTokenizerFactory: () => RuntimeTokenizerFactory | undefined;
250
+ getSessionRecordingService: () => SessionRecordingService | undefined;
249
251
  }
250
252
 
251
253
  interface ChatSessionRuntimeOptions {
@@ -275,8 +277,6 @@ function createDefaultProvider(): IProvider {
275
277
  generateChatCompletion: vi.fn(async function* () {
276
278
  yield { speaker: 'ai' as const, blocks: [] };
277
279
  }),
278
- getServerTools: () => [],
279
- invokeServerTool: vi.fn(),
280
280
  };
281
281
  }
282
282
 
@@ -347,6 +347,7 @@ export function createChatSessionRuntime(
347
347
  getProviderManager: vi.fn().mockReturnValue(providerManager),
348
348
  getSettingsService: vi.fn().mockReturnValue(settingsService),
349
349
  getTokenizerFactory: () => tokenizerFactory,
350
+ getSessionRecordingService: () => undefined,
350
351
  };
351
352
 
352
353
  const config = {