byterover-cli 0.4.0 → 1.0.0

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 (478) hide show
  1. package/README.md +1 -9
  2. package/dist/commands/curate.d.ts +1 -3
  3. package/dist/commands/curate.js +14 -51
  4. package/dist/commands/main.d.ts +8 -0
  5. package/dist/commands/main.js +29 -8
  6. package/dist/commands/query.d.ts +1 -3
  7. package/dist/commands/query.js +8 -35
  8. package/dist/config/context-tree-domains.d.ts +5 -0
  9. package/dist/config/context-tree-domains.js +6 -1
  10. package/dist/config/environment.js +9 -9
  11. package/dist/constants.d.ts +14 -0
  12. package/dist/constants.js +18 -0
  13. package/dist/core/domain/cipher/agent/agent-info.d.ts +199 -0
  14. package/dist/core/domain/cipher/agent/agent-info.js +143 -0
  15. package/dist/core/domain/cipher/agent/agent-registry.d.ts +96 -0
  16. package/dist/core/domain/cipher/agent/agent-registry.js +254 -0
  17. package/dist/core/domain/cipher/agent/index.d.ts +4 -1
  18. package/dist/core/domain/cipher/agent/index.js +7 -1
  19. package/dist/core/domain/cipher/agent-events/types.d.ts +355 -2
  20. package/dist/core/domain/cipher/agent-events/types.js +11 -0
  21. package/dist/core/domain/cipher/errors/error-normalizer.d.ts +156 -0
  22. package/dist/core/domain/cipher/errors/error-normalizer.js +379 -0
  23. package/dist/core/domain/cipher/errors/file-system-error.d.ts +2 -1
  24. package/dist/core/domain/cipher/errors/file-system-error.js +3 -2
  25. package/dist/core/domain/cipher/errors/system-prompt-error-codes.d.ts +79 -0
  26. package/dist/core/domain/cipher/errors/system-prompt-error-codes.js +80 -0
  27. package/dist/core/domain/cipher/errors/system-prompt-error.d.ts +114 -0
  28. package/dist/core/domain/cipher/errors/system-prompt-error.js +144 -0
  29. package/dist/core/domain/cipher/file-system/types.d.ts +57 -0
  30. package/dist/core/domain/cipher/llm/error-codes.d.ts +51 -0
  31. package/dist/core/domain/cipher/llm/error-codes.js +51 -0
  32. package/dist/core/domain/cipher/llm/index.d.ts +9 -0
  33. package/dist/core/domain/cipher/llm/index.js +13 -0
  34. package/dist/core/domain/cipher/llm/registry.d.ts +113 -0
  35. package/dist/core/domain/cipher/llm/registry.js +244 -0
  36. package/dist/core/domain/cipher/llm/schemas.d.ts +155 -0
  37. package/dist/core/domain/cipher/llm/schemas.js +151 -0
  38. package/dist/core/domain/cipher/llm/types.d.ts +121 -0
  39. package/dist/core/domain/cipher/llm/types.js +60 -0
  40. package/dist/core/domain/cipher/storage/message-storage-types.d.ts +114 -5
  41. package/dist/core/domain/cipher/streaming/types.d.ts +119 -0
  42. package/dist/core/domain/cipher/streaming/types.js +16 -0
  43. package/dist/core/domain/cipher/system-prompt/types.d.ts +44 -0
  44. package/dist/core/domain/cipher/todos/types.d.ts +34 -0
  45. package/dist/core/domain/cipher/tools/constants.d.ts +5 -2
  46. package/dist/core/domain/cipher/tools/constants.js +5 -2
  47. package/dist/core/domain/cipher/tools/types.d.ts +31 -0
  48. package/dist/core/domain/entities/event.d.ts +1 -1
  49. package/dist/core/domain/entities/event.js +3 -1
  50. package/dist/core/domain/errors/connection-error.d.ts +33 -0
  51. package/dist/core/domain/errors/connection-error.js +54 -0
  52. package/dist/core/domain/errors/core-process-error.d.ts +27 -0
  53. package/dist/core/domain/errors/core-process-error.js +43 -0
  54. package/dist/core/domain/errors/task-error.d.ts +64 -0
  55. package/dist/core/domain/errors/task-error.js +116 -0
  56. package/dist/core/domain/errors/transport-error.d.ts +72 -0
  57. package/dist/core/domain/errors/transport-error.js +114 -0
  58. package/dist/core/domain/instance/index.d.ts +1 -0
  59. package/dist/core/domain/instance/index.js +1 -0
  60. package/dist/core/domain/instance/types.d.ts +57 -0
  61. package/dist/core/domain/instance/types.js +72 -0
  62. package/dist/core/domain/knowledge/directory-manager.d.ts +16 -0
  63. package/dist/core/domain/knowledge/directory-manager.js +31 -0
  64. package/dist/core/domain/transport/index.d.ts +2 -0
  65. package/dist/core/domain/transport/index.js +2 -0
  66. package/dist/core/domain/transport/schemas.d.ts +1149 -0
  67. package/dist/core/domain/transport/schemas.js +554 -0
  68. package/dist/core/domain/transport/types.d.ts +67 -0
  69. package/dist/core/domain/transport/types.js +7 -0
  70. package/dist/core/interfaces/cipher/cipher-services.d.ts +15 -3
  71. package/dist/core/interfaces/cipher/i-chat-session.d.ts +47 -5
  72. package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +39 -4
  73. package/dist/core/interfaces/cipher/i-content-generator.d.ts +3 -5
  74. package/dist/core/interfaces/cipher/i-file-system.d.ts +12 -1
  75. package/dist/core/interfaces/cipher/i-llm-service.d.ts +4 -5
  76. package/dist/core/interfaces/cipher/i-todo-storage.d.ts +24 -0
  77. package/dist/core/interfaces/cipher/i-todo-storage.js +1 -0
  78. package/dist/core/interfaces/cipher/i-tool-plugin.d.ts +90 -0
  79. package/dist/core/interfaces/cipher/i-tool-plugin.js +1 -0
  80. package/dist/core/interfaces/cipher/i-tool-provider.d.ts +3 -2
  81. package/dist/core/interfaces/cipher/i-tool-scheduler.d.ts +4 -0
  82. package/dist/core/interfaces/cipher/index.d.ts +35 -0
  83. package/dist/core/interfaces/cipher/index.js +11 -0
  84. package/dist/core/interfaces/cipher/message-factory.d.ts +155 -0
  85. package/dist/core/interfaces/cipher/message-factory.js +252 -0
  86. package/dist/core/interfaces/cipher/message-type-guards.d.ts +139 -0
  87. package/dist/core/interfaces/cipher/message-type-guards.js +173 -0
  88. package/dist/core/interfaces/cipher/message-types.d.ts +279 -5
  89. package/dist/core/interfaces/cipher/message-types.js +6 -0
  90. package/dist/core/interfaces/cipher/sanitization-types.d.ts +147 -0
  91. package/dist/core/interfaces/cipher/sanitization-types.js +46 -0
  92. package/dist/core/interfaces/executor/i-curate-executor.d.ts +34 -0
  93. package/dist/core/interfaces/executor/i-curate-executor.js +1 -0
  94. package/dist/core/interfaces/executor/i-query-executor.d.ts +32 -0
  95. package/dist/core/interfaces/executor/i-query-executor.js +1 -0
  96. package/dist/core/interfaces/executor/index.d.ts +2 -0
  97. package/dist/core/interfaces/executor/index.js +2 -0
  98. package/dist/core/interfaces/instance/i-instance-discovery.d.ts +45 -0
  99. package/dist/core/interfaces/instance/i-instance-discovery.js +1 -0
  100. package/dist/core/interfaces/instance/i-instance-manager.d.ts +58 -0
  101. package/dist/core/interfaces/instance/i-instance-manager.js +1 -0
  102. package/dist/core/interfaces/instance/index.d.ts +2 -0
  103. package/dist/core/interfaces/instance/index.js +2 -0
  104. package/dist/core/interfaces/noop-implementations.d.ts +53 -0
  105. package/dist/core/interfaces/noop-implementations.js +62 -0
  106. package/dist/core/interfaces/transport/i-transport-client.d.ts +97 -0
  107. package/dist/core/interfaces/transport/i-transport-client.js +1 -0
  108. package/dist/core/interfaces/transport/i-transport-server.d.ts +93 -0
  109. package/dist/core/interfaces/transport/i-transport-server.js +1 -0
  110. package/dist/core/interfaces/transport/index.d.ts +2 -0
  111. package/dist/core/interfaces/transport/index.js +2 -0
  112. package/dist/hooks/init/welcome.js +9 -24
  113. package/dist/infra/cipher/agent/agent-error-codes.d.ts +16 -0
  114. package/dist/infra/cipher/agent/agent-error-codes.js +17 -0
  115. package/dist/infra/cipher/agent/agent-error.d.ts +54 -0
  116. package/dist/infra/cipher/agent/agent-error.js +79 -0
  117. package/dist/infra/cipher/agent/agent-schemas.d.ts +264 -0
  118. package/dist/infra/cipher/agent/agent-schemas.js +97 -0
  119. package/dist/infra/cipher/agent/agent-state-manager.d.ts +140 -0
  120. package/dist/infra/cipher/agent/agent-state-manager.js +275 -0
  121. package/dist/infra/cipher/agent/base-agent.d.ts +118 -0
  122. package/dist/infra/cipher/agent/base-agent.js +240 -0
  123. package/dist/infra/cipher/agent/cipher-agent.d.ts +165 -0
  124. package/dist/infra/cipher/agent/cipher-agent.js +546 -0
  125. package/dist/infra/cipher/agent/index.d.ts +22 -0
  126. package/dist/infra/cipher/agent/index.js +24 -0
  127. package/dist/infra/cipher/agent/service-initializer.d.ts +79 -0
  128. package/dist/infra/cipher/{agent-service-factory.js → agent/service-initializer.js} +117 -68
  129. package/dist/infra/cipher/agent/types.d.ts +35 -0
  130. package/dist/infra/cipher/agent/types.js +1 -0
  131. package/dist/infra/cipher/blob/blob-reference-resolver.d.ts +107 -0
  132. package/dist/infra/cipher/blob/blob-reference-resolver.js +228 -0
  133. package/dist/infra/cipher/blob/blob-reference-utils.d.ts +117 -0
  134. package/dist/infra/cipher/blob/blob-reference-utils.js +230 -0
  135. package/dist/infra/cipher/consumer/consumer-lock.js +1 -0
  136. package/dist/infra/cipher/consumer/consumer-service.js +1 -0
  137. package/dist/infra/cipher/consumer/execution-consumer.d.ts +6 -1
  138. package/dist/infra/cipher/consumer/execution-consumer.js +54 -16
  139. package/dist/infra/cipher/consumer/index.d.ts +1 -1
  140. package/dist/infra/cipher/consumer/index.js +2 -1
  141. package/dist/infra/cipher/consumer/queue-polling-service.js +1 -0
  142. package/dist/infra/cipher/file-system/binary-utils.d.ts +43 -0
  143. package/dist/infra/cipher/file-system/binary-utils.js +164 -0
  144. package/dist/infra/cipher/file-system/context-tree-file-system-factory.d.ts +9 -0
  145. package/dist/infra/cipher/file-system/context-tree-file-system-factory.js +24 -0
  146. package/dist/infra/cipher/file-system/file-system-service.d.ts +17 -1
  147. package/dist/infra/cipher/file-system/file-system-service.js +327 -36
  148. package/dist/infra/cipher/file-system/path-validator.d.ts +32 -0
  149. package/dist/infra/cipher/file-system/path-validator.js +111 -6
  150. package/dist/infra/cipher/interactive-loop.js +41 -33
  151. package/dist/infra/cipher/llm/capability-cache.d.ts +87 -0
  152. package/dist/infra/cipher/llm/capability-cache.js +125 -0
  153. package/dist/infra/cipher/llm/context/compaction/compaction-service.d.ts +32 -0
  154. package/dist/infra/cipher/llm/context/compaction/compaction-service.js +44 -3
  155. package/dist/infra/cipher/llm/context/compression/enhanced-compaction.d.ts +112 -0
  156. package/dist/infra/cipher/llm/context/compression/enhanced-compaction.js +175 -0
  157. package/dist/infra/cipher/llm/context/compression/filter-compacted.d.ts +83 -0
  158. package/dist/infra/cipher/llm/context/compression/filter-compacted.js +150 -0
  159. package/dist/infra/cipher/llm/context/compression/index.d.ts +5 -0
  160. package/dist/infra/cipher/llm/context/compression/index.js +6 -0
  161. package/dist/infra/cipher/llm/context/compression/reactive-overflow.d.ts +107 -0
  162. package/dist/infra/cipher/llm/context/compression/reactive-overflow.js +272 -0
  163. package/dist/infra/cipher/llm/context/context-manager.d.ts +47 -1
  164. package/dist/infra/cipher/llm/context/context-manager.js +129 -0
  165. package/dist/infra/cipher/llm/context/utils.js +17 -4
  166. package/dist/infra/cipher/llm/generators/byterover-content-generator.js +4 -2
  167. package/dist/infra/cipher/llm/internal-llm-service.d.ts +50 -17
  168. package/dist/infra/cipher/llm/internal-llm-service.js +273 -50
  169. package/dist/infra/cipher/llm/openrouter-llm-service.d.ts +6 -8
  170. package/dist/infra/cipher/llm/openrouter-llm-service.js +14 -16
  171. package/dist/infra/cipher/llm/retry/retry-policy.d.ts +1 -0
  172. package/dist/infra/cipher/llm/retry/retry-policy.js +11 -0
  173. package/dist/infra/cipher/llm/retry/retry-with-backoff.js +3 -2
  174. package/dist/infra/cipher/llm/sanitization/base64-utils.d.ts +102 -0
  175. package/dist/infra/cipher/llm/sanitization/base64-utils.js +182 -0
  176. package/dist/infra/cipher/llm/sanitization/index.d.ts +12 -0
  177. package/dist/infra/cipher/llm/sanitization/index.js +13 -0
  178. package/dist/infra/cipher/llm/sanitization/tool-sanitizer.d.ts +74 -0
  179. package/dist/infra/cipher/llm/sanitization/tool-sanitizer.js +398 -0
  180. package/dist/infra/cipher/llm/stream-processor.d.ts +158 -0
  181. package/dist/infra/cipher/llm/stream-processor.js +276 -0
  182. package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.d.ts +13 -20
  183. package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.js +17 -24
  184. package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.d.ts +12 -11
  185. package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.js +16 -15
  186. package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.d.ts +15 -7
  187. package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.js +22 -10
  188. package/dist/infra/cipher/llm/tool-output-processor.d.ts +51 -0
  189. package/dist/infra/cipher/llm/tool-output-processor.js +139 -0
  190. package/dist/infra/cipher/process/command-validator.d.ts +23 -0
  191. package/dist/infra/cipher/process/command-validator.js +75 -0
  192. package/dist/infra/cipher/process/path-utils.d.ts +66 -0
  193. package/dist/infra/cipher/process/path-utils.js +94 -0
  194. package/dist/infra/cipher/process/process-service.d.ts +32 -0
  195. package/dist/infra/cipher/process/process-service.js +98 -17
  196. package/dist/infra/cipher/session/chat-session.d.ts +56 -7
  197. package/dist/infra/cipher/session/chat-session.js +163 -13
  198. package/dist/infra/cipher/session/index.d.ts +1 -0
  199. package/dist/infra/cipher/session/index.js +2 -0
  200. package/dist/infra/cipher/session/message-queue.d.ts +65 -0
  201. package/dist/infra/cipher/session/message-queue.js +90 -0
  202. package/dist/infra/cipher/session/session-manager.d.ts +106 -5
  203. package/dist/infra/cipher/session/session-manager.js +254 -7
  204. package/dist/infra/cipher/session/session-status.d.ts +137 -0
  205. package/dist/infra/cipher/session/session-status.js +184 -0
  206. package/dist/infra/cipher/session/title-generator.d.ts +8 -0
  207. package/dist/infra/cipher/session/title-generator.js +31 -0
  208. package/dist/infra/cipher/storage/message-storage-service.d.ts +65 -2
  209. package/dist/infra/cipher/storage/message-storage-service.js +300 -54
  210. package/dist/infra/cipher/storage/tool-part-factory.d.ts +116 -0
  211. package/dist/infra/cipher/storage/tool-part-factory.js +197 -0
  212. package/dist/infra/cipher/system-prompt/contributor-schemas.d.ts +516 -0
  213. package/dist/infra/cipher/system-prompt/contributor-schemas.js +85 -0
  214. package/dist/infra/cipher/system-prompt/contributors/agent-prompt-contributor.d.ts +59 -0
  215. package/dist/infra/cipher/system-prompt/contributors/agent-prompt-contributor.js +131 -0
  216. package/dist/infra/cipher/system-prompt/contributors/companion-contributor.d.ts +54 -0
  217. package/dist/infra/cipher/system-prompt/contributors/companion-contributor.js +107 -0
  218. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.d.ts +68 -0
  219. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.js +179 -0
  220. package/dist/infra/cipher/system-prompt/contributors/datetime-contributor.d.ts +25 -0
  221. package/dist/infra/cipher/system-prompt/contributors/datetime-contributor.js +29 -0
  222. package/dist/infra/cipher/system-prompt/contributors/environment-contributor.d.ts +25 -0
  223. package/dist/infra/cipher/system-prompt/contributors/environment-contributor.js +54 -0
  224. package/dist/infra/cipher/system-prompt/contributors/file-contributor.d.ts +60 -0
  225. package/dist/infra/cipher/system-prompt/contributors/file-contributor.js +128 -0
  226. package/dist/infra/cipher/system-prompt/contributors/index.d.ts +13 -0
  227. package/dist/infra/cipher/system-prompt/contributors/index.js +8 -0
  228. package/dist/infra/cipher/system-prompt/contributors/memory-contributor.d.ts +40 -0
  229. package/dist/infra/cipher/system-prompt/contributors/memory-contributor.js +56 -0
  230. package/dist/infra/cipher/system-prompt/contributors/static-contributor.d.ts +26 -0
  231. package/dist/infra/cipher/system-prompt/contributors/static-contributor.js +31 -0
  232. package/dist/infra/cipher/system-prompt/environment-context-builder.d.ts +112 -0
  233. package/dist/infra/cipher/system-prompt/environment-context-builder.js +256 -0
  234. package/dist/infra/cipher/system-prompt/prompt-cache.d.ts +102 -0
  235. package/dist/infra/cipher/system-prompt/prompt-cache.js +156 -0
  236. package/dist/infra/cipher/system-prompt/schemas.d.ts +151 -0
  237. package/dist/infra/cipher/system-prompt/schemas.js +94 -0
  238. package/dist/infra/cipher/system-prompt/system-prompt-manager.d.ts +136 -0
  239. package/dist/infra/cipher/system-prompt/system-prompt-manager.js +307 -0
  240. package/dist/infra/cipher/todos/todo-storage-service.d.ts +26 -0
  241. package/dist/infra/cipher/todos/todo-storage-service.js +28 -0
  242. package/dist/infra/cipher/tools/core-tool-scheduler.js +5 -1
  243. package/dist/infra/cipher/tools/default-policy-rules.js +1 -1
  244. package/dist/infra/cipher/tools/implementations/bash-exec-tool.d.ts +1 -0
  245. package/dist/infra/cipher/tools/implementations/bash-exec-tool.js +27 -10
  246. package/dist/infra/cipher/tools/implementations/bash-output-tool.js +1 -5
  247. package/dist/infra/cipher/tools/implementations/batch-tool.d.ts +12 -0
  248. package/dist/infra/cipher/tools/implementations/batch-tool.js +142 -0
  249. package/dist/infra/cipher/tools/implementations/curate-tool.js +195 -68
  250. package/dist/infra/cipher/tools/implementations/list-directory-tool.d.ts +12 -0
  251. package/dist/infra/cipher/tools/implementations/list-directory-tool.js +52 -0
  252. package/dist/infra/cipher/tools/implementations/read-file-tool.d.ts +8 -1
  253. package/dist/infra/cipher/tools/implementations/read-file-tool.js +17 -7
  254. package/dist/infra/cipher/tools/implementations/read-todos-tool.d.ts +11 -0
  255. package/dist/infra/cipher/tools/implementations/read-todos-tool.js +39 -0
  256. package/dist/infra/cipher/tools/implementations/{detect-domains-tool.d.ts → spec-analyze-tool.d.ts} +1 -1
  257. package/dist/infra/cipher/tools/implementations/{detect-domains-tool.js → spec-analyze-tool.js} +9 -7
  258. package/dist/infra/cipher/tools/implementations/task-tool.d.ts +34 -0
  259. package/dist/infra/cipher/tools/implementations/task-tool.js +207 -0
  260. package/dist/infra/cipher/tools/implementations/write-todos-tool.d.ts +4 -1
  261. package/dist/infra/cipher/tools/implementations/write-todos-tool.js +19 -63
  262. package/dist/infra/cipher/tools/index.d.ts +1 -1
  263. package/dist/infra/cipher/tools/index.js +1 -1
  264. package/dist/infra/cipher/tools/plugins/index.d.ts +3 -0
  265. package/dist/infra/cipher/tools/plugins/index.js +2 -0
  266. package/dist/infra/cipher/tools/plugins/logging-plugin.d.ts +28 -0
  267. package/dist/infra/cipher/tools/plugins/logging-plugin.js +66 -0
  268. package/dist/infra/cipher/tools/plugins/plugin-manager.d.ts +81 -0
  269. package/dist/infra/cipher/tools/plugins/plugin-manager.js +122 -0
  270. package/dist/infra/cipher/tools/streaming/index.d.ts +1 -0
  271. package/dist/infra/cipher/tools/streaming/index.js +1 -0
  272. package/dist/infra/cipher/tools/streaming/metadata-handler.d.ts +31 -0
  273. package/dist/infra/cipher/tools/streaming/metadata-handler.js +39 -0
  274. package/dist/infra/cipher/tools/tool-description-loader.d.ts +57 -0
  275. package/dist/infra/cipher/tools/tool-description-loader.js +108 -0
  276. package/dist/infra/cipher/tools/tool-manager.d.ts +38 -4
  277. package/dist/infra/cipher/tools/tool-manager.js +107 -11
  278. package/dist/infra/cipher/tools/tool-provider-getter.d.ts +6 -0
  279. package/dist/infra/cipher/tools/tool-provider-getter.js +1 -0
  280. package/dist/infra/cipher/tools/tool-provider.d.ts +32 -7
  281. package/dist/infra/cipher/tools/tool-provider.js +81 -25
  282. package/dist/infra/cipher/tools/tool-registry.d.ts +23 -0
  283. package/dist/infra/cipher/tools/tool-registry.js +58 -16
  284. package/dist/infra/context-tree/file-context-tree-snapshot-service.js +10 -4
  285. package/dist/infra/context-tree/file-context-tree-writer-service.d.ts +4 -3
  286. package/dist/infra/context-tree/file-context-tree-writer-service.js +6 -4
  287. package/dist/infra/context-tree/path-utils.d.ts +7 -0
  288. package/dist/infra/context-tree/path-utils.js +7 -0
  289. package/dist/infra/core/executors/curate-executor.d.ts +35 -0
  290. package/dist/infra/core/executors/curate-executor.js +123 -0
  291. package/dist/infra/core/executors/index.d.ts +2 -0
  292. package/dist/infra/core/executors/index.js +2 -0
  293. package/dist/infra/core/executors/query-executor.d.ts +23 -0
  294. package/dist/infra/core/executors/query-executor.js +51 -0
  295. package/dist/infra/core/task-processor.d.ts +81 -0
  296. package/dist/infra/core/task-processor.js +115 -0
  297. package/dist/infra/instance/file-instance-discovery.d.ts +31 -0
  298. package/dist/infra/instance/file-instance-discovery.js +84 -0
  299. package/dist/infra/instance/file-instance-manager.d.ts +46 -0
  300. package/dist/infra/instance/file-instance-manager.js +123 -0
  301. package/dist/infra/instance/index.d.ts +3 -0
  302. package/dist/infra/instance/index.js +3 -0
  303. package/dist/infra/instance/process-utils.d.ts +14 -0
  304. package/dist/infra/instance/process-utils.js +39 -0
  305. package/dist/infra/process/agent-worker.d.ts +20 -0
  306. package/dist/infra/process/agent-worker.js +602 -0
  307. package/dist/infra/process/index.d.ts +12 -0
  308. package/dist/infra/process/index.js +11 -0
  309. package/dist/infra/process/ipc-types.d.ts +55 -0
  310. package/dist/infra/process/ipc-types.js +12 -0
  311. package/dist/infra/process/process-manager.d.ts +154 -0
  312. package/dist/infra/process/process-manager.js +471 -0
  313. package/dist/infra/process/task-queue-manager.d.ts +123 -0
  314. package/dist/infra/process/task-queue-manager.js +226 -0
  315. package/dist/infra/process/transport-handlers.d.ts +124 -0
  316. package/dist/infra/process/transport-handlers.js +348 -0
  317. package/dist/infra/process/transport-worker.d.ts +20 -0
  318. package/dist/infra/process/transport-worker.js +168 -0
  319. package/dist/infra/repl/commands/curate-command.js +0 -5
  320. package/dist/infra/repl/commands/query-command.js +0 -3
  321. package/dist/infra/repl/repl-startup.d.ts +4 -0
  322. package/dist/infra/repl/repl-startup.js +10 -1
  323. package/dist/infra/repl/transport-client-helper.d.ts +9 -0
  324. package/dist/infra/repl/transport-client-helper.js +96 -0
  325. package/dist/infra/transport/index.d.ts +4 -0
  326. package/dist/infra/transport/index.js +4 -0
  327. package/dist/infra/transport/port-utils.d.ts +42 -0
  328. package/dist/infra/transport/port-utils.js +84 -0
  329. package/dist/infra/transport/socket-io-transport-client.d.ts +45 -0
  330. package/dist/infra/transport/socket-io-transport-client.js +270 -0
  331. package/dist/infra/transport/socket-io-transport-server.d.ts +35 -0
  332. package/dist/infra/transport/socket-io-transport-server.js +207 -0
  333. package/dist/infra/transport/transport-client-factory.d.ts +76 -0
  334. package/dist/infra/transport/transport-client-factory.js +168 -0
  335. package/dist/infra/transport/transport-factory.d.ts +33 -0
  336. package/dist/infra/transport/transport-factory.js +59 -0
  337. package/dist/infra/usecase/curate-use-case.d.ts +8 -55
  338. package/dist/infra/usecase/curate-use-case.js +73 -259
  339. package/dist/infra/usecase/init-use-case.js +19 -8
  340. package/dist/infra/usecase/login-use-case.js +9 -3
  341. package/dist/infra/usecase/query-use-case.d.ts +18 -45
  342. package/dist/infra/usecase/query-use-case.js +251 -326
  343. package/dist/infra/usecase/status-use-case.js +1 -1
  344. package/dist/resources/prompts/{curate-context-tree-curation.yml → curate.yml} +25 -22
  345. package/dist/resources/prompts/explore.yml +78 -0
  346. package/dist/resources/prompts/plan.yml +114 -0
  347. package/dist/resources/prompts/reflection.yml +1 -1
  348. package/dist/resources/prompts/system-prompt.yml +15 -8
  349. package/dist/resources/prompts/tool-outputs.yml +0 -5
  350. package/dist/resources/tools/bash_exec.txt +98 -0
  351. package/dist/resources/tools/bash_output.txt +40 -0
  352. package/dist/resources/tools/batch.txt +28 -0
  353. package/dist/resources/tools/create_knowledge_topic.txt +23 -0
  354. package/dist/resources/tools/curate.txt +22 -0
  355. package/dist/resources/tools/delete_memory.txt +1 -0
  356. package/dist/resources/tools/detect_domains.txt +11 -0
  357. package/dist/resources/tools/edit_file.txt +1 -0
  358. package/dist/resources/tools/edit_memory.txt +1 -0
  359. package/dist/resources/tools/glob_files.txt +20 -0
  360. package/dist/resources/tools/grep_content.txt +18 -0
  361. package/dist/resources/tools/kill_process.txt +16 -0
  362. package/dist/resources/tools/list_directory.txt +16 -0
  363. package/dist/resources/tools/list_memories.txt +1 -0
  364. package/dist/resources/tools/read_file.txt +31 -0
  365. package/dist/resources/tools/read_memory.txt +1 -0
  366. package/dist/resources/tools/read_todos.txt +17 -0
  367. package/dist/resources/tools/search_history.txt +1 -0
  368. package/dist/resources/tools/task.txt +23 -0
  369. package/dist/resources/tools/write_file.txt +1 -0
  370. package/dist/resources/tools/write_memory.txt +1 -0
  371. package/dist/resources/tools/write_todos.txt +29 -0
  372. package/dist/tui/app.js +9 -13
  373. package/dist/tui/components/command-details.d.ts +14 -0
  374. package/dist/tui/components/command-details.js +35 -0
  375. package/dist/tui/components/execution/execution-changes.d.ts +5 -0
  376. package/dist/tui/components/execution/execution-changes.js +19 -4
  377. package/dist/tui/components/execution/execution-content.d.ts +4 -2
  378. package/dist/tui/components/execution/execution-content.js +26 -13
  379. package/dist/tui/components/execution/execution-input.js +3 -3
  380. package/dist/tui/components/execution/execution-progress.d.ts +2 -2
  381. package/dist/tui/components/execution/execution-progress.js +8 -6
  382. package/dist/tui/components/execution/log-item.d.ts +3 -4
  383. package/dist/tui/components/execution/log-item.js +2 -5
  384. package/dist/tui/components/footer.js +9 -4
  385. package/dist/tui/components/header.d.ts +3 -3
  386. package/dist/tui/components/header.js +5 -3
  387. package/dist/tui/components/index.d.ts +1 -0
  388. package/dist/tui/components/index.js +1 -0
  389. package/dist/tui/components/onboarding/copyable-prompt.d.ts +5 -3
  390. package/dist/tui/components/onboarding/copyable-prompt.js +7 -8
  391. package/dist/tui/components/onboarding/onboarding-flow.js +35 -25
  392. package/dist/tui/components/scrollable-list.js +12 -10
  393. package/dist/tui/components/suggestions.js +39 -41
  394. package/dist/tui/components/tab-bar.d.ts +2 -1
  395. package/dist/tui/components/tab-bar.js +3 -4
  396. package/dist/tui/constants.d.ts +0 -5
  397. package/dist/tui/constants.js +0 -5
  398. package/dist/tui/contexts/auth-context.js +9 -2
  399. package/dist/tui/contexts/{use-commands.js → commands-context.js} +6 -5
  400. package/dist/tui/contexts/index.d.ts +6 -1
  401. package/dist/tui/contexts/index.js +6 -1
  402. package/dist/tui/contexts/onboarding-context.d.ts +1 -1
  403. package/dist/tui/contexts/onboarding-context.js +9 -9
  404. package/dist/tui/contexts/tasks-context.d.ts +84 -0
  405. package/dist/tui/contexts/tasks-context.js +218 -0
  406. package/dist/tui/contexts/transport-context.d.ts +29 -0
  407. package/dist/tui/contexts/transport-context.js +82 -0
  408. package/dist/tui/hooks/index.d.ts +10 -6
  409. package/dist/tui/hooks/index.js +7 -6
  410. package/dist/tui/hooks/use-activity-logs.d.ts +3 -11
  411. package/dist/tui/hooks/use-activity-logs.js +87 -34
  412. package/dist/tui/hooks/use-auth-polling.d.ts +24 -0
  413. package/dist/tui/hooks/use-auth-polling.js +104 -0
  414. package/dist/tui/hooks/use-slash-command-processor.js +0 -1
  415. package/dist/tui/hooks/use-slash-completion.js +1 -1
  416. package/dist/tui/hooks/use-tab-navigation.d.ts +2 -1
  417. package/dist/tui/hooks/use-tab-navigation.js +16 -7
  418. package/dist/tui/hooks/use-terminal-breakpoint.d.ts +21 -0
  419. package/dist/tui/hooks/use-terminal-breakpoint.js +38 -0
  420. package/dist/tui/hooks/use-ui-heights.d.ts +120 -0
  421. package/dist/tui/hooks/use-ui-heights.js +88 -0
  422. package/dist/tui/providers/app-providers.js +2 -6
  423. package/dist/tui/types/commands.d.ts +0 -26
  424. package/dist/tui/types/index.d.ts +1 -1
  425. package/dist/tui/types/ui.d.ts +9 -4
  426. package/dist/tui/utils/line.d.ts +11 -0
  427. package/dist/tui/utils/line.js +16 -0
  428. package/dist/tui/utils/log.d.ts +27 -0
  429. package/dist/tui/utils/log.js +114 -0
  430. package/dist/tui/views/command-view.d.ts +7 -0
  431. package/dist/tui/views/command-view.js +103 -80
  432. package/dist/tui/views/login-view.js +7 -4
  433. package/dist/tui/views/logs-view.d.ts +13 -0
  434. package/dist/tui/views/logs-view.js +27 -52
  435. package/dist/utils/connection-error-handler.d.ts +16 -0
  436. package/dist/utils/connection-error-handler.js +49 -0
  437. package/dist/utils/crash-log.d.ts +14 -0
  438. package/dist/utils/crash-log.js +19 -0
  439. package/dist/utils/file-helpers.d.ts +14 -0
  440. package/dist/utils/file-helpers.js +21 -0
  441. package/dist/utils/global-logs-path.d.ts +11 -0
  442. package/dist/utils/global-logs-path.js +37 -0
  443. package/dist/utils/process-logger.d.ts +53 -0
  444. package/dist/utils/process-logger.js +253 -0
  445. package/dist/utils/sandbox-detector.d.ts +31 -0
  446. package/dist/utils/sandbox-detector.js +122 -0
  447. package/oclif.manifest.json +10 -198
  448. package/package.json +5 -1
  449. package/dist/commands/cipher-agent/run.d.ts +0 -142
  450. package/dist/commands/cipher-agent/run.js +0 -555
  451. package/dist/commands/cipher-agent/set-prompt.d.ts +0 -16
  452. package/dist/commands/cipher-agent/set-prompt.js +0 -58
  453. package/dist/commands/cipher-agent/show-prompt.d.ts +0 -13
  454. package/dist/commands/cipher-agent/show-prompt.js +0 -53
  455. package/dist/commands/foo.d.ts +0 -14
  456. package/dist/commands/foo.js +0 -66
  457. package/dist/infra/cipher/agent-service-factory.d.ts +0 -93
  458. package/dist/infra/cipher/cipher-agent-state-manager.d.ts +0 -63
  459. package/dist/infra/cipher/cipher-agent-state-manager.js +0 -108
  460. package/dist/infra/cipher/cipher-agent.d.ts +0 -182
  461. package/dist/infra/cipher/cipher-agent.js +0 -317
  462. package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +0 -106
  463. package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +0 -297
  464. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.d.ts +0 -7
  465. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +0 -424
  466. package/dist/resources/prompts/modes/autonomous.yml +0 -9
  467. package/dist/resources/prompts/query-context-tree-retrieval.yml +0 -48
  468. package/dist/tui/contexts/consumer.d.ts +0 -31
  469. package/dist/tui/contexts/consumer.js +0 -56
  470. package/dist/tui/hooks/use-consumer.d.ts +0 -12
  471. package/dist/tui/hooks/use-consumer.js +0 -50
  472. package/dist/tui/hooks/use-queue-polling.d.ts +0 -31
  473. package/dist/tui/hooks/use-queue-polling.js +0 -90
  474. /package/dist/tui/contexts/{use-commands.d.ts → commands-context.d.ts} +0 -0
  475. /package/dist/tui/contexts/{use-mode.d.ts → mode-context.d.ts} +0 -0
  476. /package/dist/tui/contexts/{use-mode.js → mode-context.js} +0 -0
  477. /package/dist/tui/contexts/{use-theme.d.ts → theme-context.d.ts} +0 -0
  478. /package/dist/tui/contexts/{use-theme.js → theme-context.js} +0 -0
@@ -1,8 +1,11 @@
1
1
  import { AgentStateMachine } from '../../../core/domain/cipher/agent/agent-state-machine.js';
2
2
  import { AgentState, TerminationReason } from '../../../core/domain/cipher/agent/agent-state.js';
3
3
  import { LlmGenerationError, LlmMaxIterationsError, LlmResponseParsingError, } from '../../../core/domain/cipher/errors/llm-error.js';
4
+ import { getEffectiveMaxInputTokens, getMaxInputTokensForModel, getProviderFromModel, isValidProviderModel, safeParseLLMConfig, } from '../../../core/domain/cipher/llm/index.js';
4
5
  import { NoOpLogger } from '../../../core/interfaces/cipher/i-logger.js';
5
6
  import { getErrorMessage } from '../../../utils/error-helpers.js';
7
+ import { EnvironmentContextBuilder } from '../system-prompt/environment-context-builder.js';
8
+ import { ToolMetadataHandler } from '../tools/streaming/metadata-handler.js';
6
9
  import { ContextManager } from './context/context-manager.js';
7
10
  import { LoopDetector } from './context/loop-detector.js';
8
11
  import { ClaudeMessageFormatter } from './formatters/claude-formatter.js';
@@ -29,19 +32,24 @@ import { ToolOutputProcessor } from './tool-output-processor.js';
29
32
  * - Handle retry logic (handled by RetryableContentGenerator decorator)
30
33
  */
31
34
  export class ByteRoverLLMService {
35
+ compactionService;
32
36
  config;
33
37
  contextManager;
38
+ environmentBuilder;
34
39
  formatter;
35
40
  generator;
36
41
  logger;
37
42
  loopDetector;
38
43
  memoryManager;
44
+ metadataHandler;
39
45
  outputProcessor;
40
- promptFactory;
41
46
  providerType;
42
47
  sessionEventBus;
48
+ sessionId;
49
+ systemPromptManager;
43
50
  tokenizer;
44
51
  toolManager;
52
+ workingDirectory;
45
53
  /**
46
54
  * Initialize a new ByteRover LLM service instance.
47
55
  *
@@ -59,33 +67,44 @@ export class ByteRoverLLMService {
59
67
  * @param config - LLM service configuration (model, tokens, temperature)
60
68
  * @param options - Service dependencies
61
69
  * @param options.toolManager - Tool manager for executing agent tools
62
- * @param options.promptFactory - Simple prompt factory for building system prompts
70
+ * @param options.systemPromptManager - System prompt manager for building system prompts
63
71
  * @param options.memoryManager - Memory manager for agent memories
64
72
  * @param options.sessionEventBus - Event bus for session lifecycle events
73
+ * @param options.compactionService - Optional compaction service for context overflow management
65
74
  * @param options.historyStorage - Optional history storage for persistence
66
75
  * @param options.logger - Optional logger for structured logging
67
76
  */
68
77
  constructor(sessionId, generator, config, options) {
78
+ this.sessionId = sessionId;
69
79
  this.generator = generator;
80
+ this.compactionService = options.compactionService;
70
81
  this.toolManager = options.toolManager;
71
- this.promptFactory = options.promptFactory;
82
+ this.systemPromptManager = options.systemPromptManager;
72
83
  this.memoryManager = options.memoryManager;
73
84
  this.sessionEventBus = options.sessionEventBus;
74
85
  this.logger = options.logger ?? new NoOpLogger();
75
86
  this.outputProcessor = new ToolOutputProcessor(config.truncationConfig);
76
87
  this.loopDetector = new LoopDetector();
88
+ this.environmentBuilder = new EnvironmentContextBuilder();
89
+ this.metadataHandler = new ToolMetadataHandler(this.sessionEventBus);
90
+ this.workingDirectory = process.cwd();
91
+ // Detect provider type from model name (needed for validation)
92
+ const modelName = config.model ?? 'claude-haiku-4-5@20251001';
93
+ this.providerType = this.detectProviderType(modelName);
94
+ // Validate core LLM config using Zod schema (logs warning if invalid)
95
+ this.validateConfig(modelName, config.maxInputTokens);
96
+ // Get effective max input tokens from registry (respects model limits)
97
+ const effectiveMaxInputTokens = getEffectiveMaxInputTokens(this.providerType, modelName, config.maxInputTokens);
77
98
  this.config = {
78
- maxInputTokens: config.maxInputTokens ?? 1_000_000,
99
+ maxInputTokens: effectiveMaxInputTokens,
79
100
  maxIterations: config.maxIterations ?? 50,
80
101
  maxTokens: config.maxTokens ?? 8192,
81
- model: config.model ?? 'claude-haiku-4-5@20251001',
102
+ model: modelName,
82
103
  temperature: config.temperature ?? 0.7,
83
104
  thinkingConfig: config.thinkingConfig,
84
105
  timeout: config.timeout,
85
106
  verbose: config.verbose ?? false,
86
107
  };
87
- // Detect provider type from model name
88
- this.providerType = this.detectProviderType(this.config.model);
89
108
  // Initialize formatter and tokenizer based on provider type
90
109
  if (this.providerType === 'claude') {
91
110
  this.formatter = new ClaudeMessageFormatter();
@@ -114,19 +133,18 @@ export class ByteRoverLLMService {
114
133
  * 3. Returning final response when no more tool calls
115
134
  *
116
135
  * @param textInput - User input text
117
- * @param sessionId - Session ID for tracking the llm request in a command session
118
136
  * @param options - Execution options
119
137
  * @param options.executionContext - Optional execution context
120
138
  * @param options.signal - Optional abort signal for cancellation
121
139
  * @param options.imageData - Optional image data
122
140
  * @param options.fileData - Optional file data
123
141
  * @param options.stream - Whether to stream response (not implemented yet)
124
- * @param options.mode - Optional mode for system prompt ('autonomous' enables autonomous mode)
142
+ * @param options.taskId - Task ID from usecase for billing tracking
125
143
  * @returns Final assistant response
126
144
  */
127
- async completeTask(textInput, sessionId, options) {
145
+ async completeTask(textInput, options) {
128
146
  // Extract options with defaults
129
- const { executionContext, fileData, imageData, mode, signal } = options ?? {};
147
+ const { executionContext, fileData, imageData, signal, taskId } = options ?? {};
130
148
  // Add user message to context
131
149
  await this.contextManager.addUserMessage(textInput, imageData, fileData);
132
150
  // Get filtered tools based on command type (e.g., only read-only tools for 'query')
@@ -152,8 +170,7 @@ export class ByteRoverLLMService {
152
170
  const result = await this.executeAgenticIteration({
153
171
  executionContext,
154
172
  iterationCount: stateMachine.getContext().turnCount,
155
- mode,
156
- sessionId,
173
+ taskId,
157
174
  tools: toolSet,
158
175
  });
159
176
  if (result !== null) {
@@ -198,10 +215,12 @@ export class ByteRoverLLMService {
198
215
  * @returns Service configuration object with model info and constraints
199
216
  */
200
217
  getConfig() {
218
+ // Get model's actual max tokens from registry
219
+ const modelMaxTokens = getMaxInputTokensForModel(this.providerType, this.config.model);
201
220
  return {
202
221
  configuredMaxInputTokens: this.config.maxInputTokens,
203
222
  model: this.config.model,
204
- modelMaxInputTokens: this.config.maxInputTokens,
223
+ modelMaxInputTokens: modelMaxTokens,
205
224
  provider: 'byterover',
206
225
  router: 'in-built',
207
226
  };
@@ -243,7 +262,10 @@ export class ByteRoverLLMService {
243
262
  const { toolCall, toolResult } = result;
244
263
  if (!toolResult) {
245
264
  // This shouldn't happen, but handle gracefully
246
- await this.contextManager.addToolResult(toolCall.id, toolCall.function.name, 'Error: No tool result available', { errorType: 'NO_RESULT', success: false });
265
+ await this.contextManager.addToolResult(toolCall.id, toolCall.function.name, 'Error: No tool result available', {
266
+ errorType: 'NO_RESULT',
267
+ success: false,
268
+ });
247
269
  return;
248
270
  }
249
271
  await this.contextManager.addToolResult(toolCall.id, toolCall.function.name, toolResult.processedOutput.content, {
@@ -257,14 +279,13 @@ export class ByteRoverLLMService {
257
279
  *
258
280
  * Converts internal context to the standardized GenerateContentRequest format.
259
281
  *
260
- * @param sessionId - Session ID for tracking the llm request in a command session
261
- * @param systemPrompt - System prompt text
262
- * @param tools - Available tools for function calling
263
- * @param mode - Optional mode for system prompt
264
- * @param executionContext - Optional execution context
282
+ * @param options - Request options
283
+ * @param options.systemPrompt - System prompt text
284
+ * @param options.tools - Available tools for function calling
285
+ * @param options.executionContext - Optional execution context
265
286
  * @returns GenerateContentRequest for the generator
266
287
  */
267
- buildGenerateContentRequest(sessionId, systemPrompt, tools, mode, executionContext) {
288
+ buildGenerateContentRequest(options) {
268
289
  // Get internal messages from context manager
269
290
  const messages = this.contextManager.getMessages();
270
291
  return {
@@ -273,12 +294,11 @@ export class ByteRoverLLMService {
273
294
  temperature: this.config.temperature,
274
295
  },
275
296
  contents: messages,
276
- executionContext,
277
- mode,
297
+ executionContext: options.executionContext,
278
298
  model: this.config.model,
279
- sessionId,
280
- systemPrompt,
281
- tools,
299
+ systemPrompt: options.systemPrompt,
300
+ taskId: options.taskId ?? '',
301
+ tools: options.tools,
282
302
  };
283
303
  }
284
304
  /**
@@ -316,12 +336,95 @@ export class ByteRoverLLMService {
316
336
  }
317
337
  }
318
338
  /**
319
- * Detect provider type from model name.
339
+ * Check for context overflow and trigger compaction if needed.
340
+ * Called after each assistant response and after tool execution batches.
341
+ *
342
+ * Follows OpenCode's compaction patterns:
343
+ * - First tries pruning tool outputs (if overflow > 85%)
344
+ * - Then tries full compaction with LLM summary (if overflow > 95%)
345
+ *
346
+ * @param taskId - Task ID from usecase for billing tracking (passed from caller)
347
+ */
348
+ async checkAndTriggerCompaction(taskId) {
349
+ if (!this.compactionService)
350
+ return;
351
+ // Calculate current token usage
352
+ const messages = this.contextManager.getMessages();
353
+ const messagesTokens = messages.reduce((total, msg) => total +
354
+ this.generator.estimateTokensSync(typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content)), 0);
355
+ // Estimate system prompt tokens (rough estimate since we don't have full context here)
356
+ // Using a conservative estimate of 2000 tokens for system prompt
357
+ const estimatedSystemPromptTokens = 2000;
358
+ const currentTokens = estimatedSystemPromptTokens + messagesTokens;
359
+ // Check overflow
360
+ const overflowResult = this.compactionService.checkOverflow(currentTokens, this.config.maxInputTokens);
361
+ if (!overflowResult.isOverflow)
362
+ return;
363
+ // Emit context overflow event
364
+ const utilizationPercent = Math.round((currentTokens / this.config.maxInputTokens) * 100);
365
+ this.sessionEventBus.emit('llmservice:contextOverflow', {
366
+ currentTokens,
367
+ maxTokens: this.config.maxInputTokens,
368
+ utilizationPercent,
369
+ });
370
+ if (overflowResult.recommendation === 'prune') {
371
+ // Try pruning tool outputs first
372
+ const pruneResult = await this.compactionService.pruneToolOutputs(this.sessionId);
373
+ if (this.config.verbose && pruneResult.compactedCount > 0) {
374
+ console.log(`[Compaction] Pruned ${pruneResult.compactedCount} tool outputs, saved ~${pruneResult.tokensSaved} tokens`);
375
+ }
376
+ // Emit context pruned event
377
+ if (pruneResult.compactedCount > 0) {
378
+ this.sessionEventBus.emit('llmservice:contextPruned', {
379
+ pruneCount: pruneResult.compactedCount,
380
+ reason: 'overflow',
381
+ tokensSaved: pruneResult.tokensSaved,
382
+ });
383
+ // Also emit warning for backward compatibility
384
+ this.sessionEventBus.emit('llmservice:warning', {
385
+ message: `Context compaction: pruned ${pruneResult.compactedCount} old tool outputs (~${pruneResult.tokensSaved} tokens)`,
386
+ });
387
+ }
388
+ }
389
+ else if (overflowResult.recommendation === 'compact') {
390
+ const originalTokens = currentTokens;
391
+ // Full compaction needed - generate LLM summary
392
+ // Use the same taskId from caller for billing tracking
393
+ const summary = await this.compactionService.generateSummary(this.generator, messages, taskId, this.config.model);
394
+ await this.compactionService.createCompactionBoundary(this.sessionId, summary);
395
+ if (this.config.verbose) {
396
+ console.log('[Compaction] Created compaction boundary with LLM-generated summary');
397
+ }
398
+ // Emit context compressed event
399
+ // Estimate compressed tokens (summary is much smaller than original)
400
+ const compressedTokens = this.generator.estimateTokensSync(summary);
401
+ this.sessionEventBus.emit('llmservice:contextCompressed', {
402
+ compressedTokens,
403
+ originalTokens,
404
+ strategy: 'summary',
405
+ });
406
+ // Also emit warning for backward compatibility
407
+ this.sessionEventBus.emit('llmservice:warning', {
408
+ message: 'Context compaction: created summary boundary for conversation history',
409
+ });
410
+ }
411
+ }
412
+ /**
413
+ * Detect provider type from model name using the LLM registry.
414
+ *
415
+ * Uses the centralized registry to determine provider from model name.
416
+ * Falls back to string prefix matching if model is not in registry.
320
417
  *
321
418
  * @param model - Model identifier
322
419
  * @returns Provider type ('claude' or 'gemini')
323
420
  */
324
421
  detectProviderType(model) {
422
+ // Use registry to detect provider
423
+ const registryProvider = getProviderFromModel(model);
424
+ if (registryProvider === 'claude' || registryProvider === 'gemini') {
425
+ return registryProvider;
426
+ }
427
+ // Fallback to string prefix matching for unknown models
325
428
  return model.toLowerCase().startsWith('claude') ? 'claude' : 'gemini';
326
429
  }
327
430
  /**
@@ -368,15 +471,14 @@ export class ByteRoverLLMService {
368
471
  *
369
472
  * @param options - Iteration options
370
473
  * @param options.iterationCount - Current iteration number
371
- * @param options.sessionId - Session ID for tracking the llm request in a command session
474
+ * @param options.taskId - Task ID from usecase for billing tracking
372
475
  * @param options.tools - Available tools for this iteration
373
- * @param options.mode - Optional mode for system prompt
374
476
  * @param options.executionContext - Optional execution context
375
477
  * @returns Final response string if complete, null if more iterations needed
376
478
  */
377
479
  async executeAgenticIteration(options) {
378
- const { executionContext, iterationCount, mode, sessionId, tools } = options;
379
- // Build system prompt using SimplePromptFactory (before compression for correct token accounting)
480
+ const { executionContext, iterationCount, taskId, tools } = options;
481
+ // Build system prompt using SystemPromptManager (before compression for correct token accounting)
380
482
  // Use filtered tool names based on command type (e.g., only read-only tools for 'query')
381
483
  const availableTools = this.toolManager.getToolNamesForCommand(executionContext?.commandType);
382
484
  const markersSet = this.toolManager.getAvailableMarkers();
@@ -385,20 +487,28 @@ export class ByteRoverLLMService {
385
487
  for (const marker of markersSet) {
386
488
  availableMarkers[marker] = marker;
387
489
  }
388
- let systemPrompt = await this.promptFactory.buildSystemPrompt({
490
+ // Build environment context for system prompt
491
+ const environmentContext = await this.environmentBuilder.build({
492
+ includeBrvStructure: true,
493
+ includeFileTree: true,
494
+ maxFileTreeDepth: 3,
495
+ maxFileTreeEntries: 100,
496
+ workingDirectory: this.workingDirectory,
497
+ });
498
+ let systemPrompt = await this.systemPromptManager.build({
389
499
  availableMarkers,
390
500
  availableTools,
391
501
  commandType: executionContext?.commandType,
392
502
  conversationMetadata: executionContext?.conversationMetadata,
503
+ environmentContext,
393
504
  fileReferenceInstructions: executionContext?.fileReferenceInstructions,
394
505
  memoryManager: this.memoryManager,
395
- mode,
396
506
  });
397
507
  // Determine which reflection prompt to add (only highest priority is chosen)
398
508
  const reflectionType = this.determineReflectionType(iterationCount, executionContext?.commandType);
399
509
  // Add reflection prompt if eligible (hierarchical: only one reflection per iteration)
400
510
  if (reflectionType) {
401
- const reflectionPrompt = this.promptFactory.buildReflectionPrompt({
511
+ const reflectionPrompt = this.systemPromptManager.buildReflectionPrompt({
402
512
  currentIteration: iterationCount + 1,
403
513
  maxIterations: this.config.maxIterations,
404
514
  type: reflectionType,
@@ -437,15 +547,25 @@ export class ByteRoverLLMService {
437
547
  toolsForThisIteration = {}; // Empty toolset forces text response
438
548
  }
439
549
  // Build generation request
440
- const request = this.buildGenerateContentRequest(sessionId, systemPrompt, toolsForThisIteration, mode, executionContext);
550
+ const request = this.buildGenerateContentRequest({
551
+ executionContext,
552
+ systemPrompt,
553
+ taskId,
554
+ tools: toolsForThisIteration,
555
+ });
441
556
  // Call LLM via generator (retry + logging handled by decorators)
442
557
  const lastMessage = await this.callLLMAndParseResponse(request);
443
558
  // Check if there are tool calls
444
559
  if (!lastMessage.toolCalls || lastMessage.toolCalls.length === 0) {
445
- return this.handleFinalResponse(lastMessage);
560
+ const response = await this.handleFinalResponse(lastMessage);
561
+ // Auto-compaction check after assistant response
562
+ await this.checkAndTriggerCompaction(taskId ?? '');
563
+ return response;
446
564
  }
447
- // Has tool calls - handle them
448
- await this.handleToolCalls(lastMessage);
565
+ // Has tool calls - handle them (pass taskId for subagent billing)
566
+ await this.handleToolCalls(lastMessage, taskId);
567
+ // Auto-compaction check after tool execution batch
568
+ await this.checkAndTriggerCompaction(taskId ?? '');
449
569
  return null;
450
570
  }
451
571
  /**
@@ -453,26 +573,37 @@ export class ByteRoverLLMService {
453
573
  * Returns all information needed to add the result to context later.
454
574
  *
455
575
  * @param toolCall - Tool call to execute
576
+ * @param taskId - Task ID from usecase for billing tracking (passed to subagents)
456
577
  * @returns Parallel tool result with all execution data
457
578
  */
458
- async executeToolCallParallel(toolCall) {
579
+ async executeToolCallParallel(toolCall, taskId) {
459
580
  const toolName = toolCall.function.name;
460
581
  const toolArgs = JSON.parse(toolCall.function.arguments);
461
582
  try {
462
583
  // Check for loops before execution (mutex-protected)
463
584
  const loopResult = await this.loopDetector.recordAndCheck(toolName, toolArgs);
464
585
  if (loopResult.isLoop) {
465
- // Emit warning event
586
+ // Emit dedicated doom loop event for observability
587
+ this.sessionEventBus.emit('llmservice:doomLoopDetected', {
588
+ args: toolArgs,
589
+ loopType: loopResult.loopType,
590
+ repeatCount: loopResult.repeatCount ?? 0,
591
+ toolName,
592
+ });
593
+ // Also emit warning event for backward compatibility
466
594
  this.sessionEventBus.emit('llmservice:warning', {
467
- message: `Loop detected: ${loopResult.loopType} - tool "${toolName}" repeated ${loopResult.repeatCount} times`,
595
+ message: `Doom loop detected: ${loopResult.loopType} - tool "${toolName}" repeated ${loopResult.repeatCount} times. Auto-denying to prevent infinite loop.`,
468
596
  });
469
597
  return {
470
598
  toolCall,
471
599
  toolResult: {
472
600
  errorType: 'LOOP_DETECTED',
473
- metadata: {},
601
+ metadata: {
602
+ loopType: loopResult.loopType,
603
+ repeatCount: loopResult.repeatCount,
604
+ },
474
605
  processedOutput: {
475
- content: `⚠️ LOOP DETECTED: ${loopResult.suggestion}\n\nPlease try a different approach to accomplish your goal.`,
606
+ content: `⚠️ DOOM LOOP DETECTED: ${loopResult.suggestion}\n\nThe tool call has been automatically rejected to prevent an infinite loop. Please try a different approach to accomplish your goal.`,
476
607
  },
477
608
  success: false,
478
609
  },
@@ -484,8 +615,14 @@ export class ByteRoverLLMService {
484
615
  callId: toolCall.id,
485
616
  toolName,
486
617
  });
618
+ // Create metadata callback for streaming tool output
619
+ const metadataCallback = this.metadataHandler.createCallback(toolCall.id, toolName);
487
620
  // Execute tool via ToolManager (returns structured result)
488
- const result = await this.toolManager.executeTool(toolName, toolArgs);
621
+ // Pass taskId in context for subagent billing tracking
622
+ const result = await this.toolManager.executeTool(toolName, toolArgs, this.sessionId, {
623
+ metadata: metadataCallback,
624
+ taskId,
625
+ });
489
626
  // Process output (truncation and file saving if needed)
490
627
  const processedOutput = await this.outputProcessor.processOutput(toolName, result.content);
491
628
  // Emit truncation event if output was truncated
@@ -682,11 +819,13 @@ export class ByteRoverLLMService {
682
819
  }
683
820
  /**
684
821
  * Handle tool calls from LLM response.
685
- * Executes tools in parallel for performance, but adds results to context in order.
822
+ * Uses tool parts with state machine: pending running completed/error.
823
+ * Executes tools in parallel for performance, but updates state in order.
686
824
  *
687
825
  * @param lastMessage - Last message containing tool calls
826
+ * @param taskId - Task ID from usecase for billing tracking (passed to subagents)
688
827
  */
689
- async handleToolCalls(lastMessage) {
828
+ async handleToolCalls(lastMessage, taskId) {
690
829
  if (!lastMessage.toolCalls || lastMessage.toolCalls.length === 0) {
691
830
  return;
692
831
  }
@@ -695,26 +834,76 @@ export class ByteRoverLLMService {
695
834
  // Has tool calls - add assistant message with tool calls
696
835
  const assistantContent = this.extractTextContent(lastMessage);
697
836
  await this.contextManager.addAssistantMessage(assistantContent, lastMessage.toolCalls);
698
- // Execute all tool calls in parallel
699
- const parallelResults = await Promise.allSettled(lastMessage.toolCalls.map((toolCall) => this.executeToolCallParallel(toolCall)));
700
- // Add results to context IN ORDER (preserves conversation flow)
837
+ // Step 1: Create pending tool parts for all tool calls
838
+ for (const toolCall of lastMessage.toolCalls) {
839
+ const toolArgs = JSON.parse(toolCall.function.arguments);
840
+ this.contextManager.addToolCallPending(toolCall.id, toolCall.function.name, toolArgs);
841
+ }
842
+ // Step 2: Transition all to running state
843
+ const startTime = Date.now();
844
+ for (const toolCall of lastMessage.toolCalls) {
845
+ const runningState = {
846
+ input: JSON.parse(toolCall.function.arguments),
847
+ startedAt: startTime,
848
+ status: 'running',
849
+ };
850
+ this.contextManager.updateToolCallState(toolCall.id, runningState);
851
+ }
852
+ // Step 3: Execute all tool calls in parallel (pass taskId for subagent billing)
853
+ const parallelResults = await Promise.allSettled(lastMessage.toolCalls.map((toolCall) => this.executeToolCallParallel(toolCall, taskId)));
854
+ // Step 4: Update tool part states with results (in order)
855
+ const endTime = Date.now();
701
856
  // eslint-disable-next-line unicorn/no-for-loop -- Need index to access both parallelResults and toolCalls in parallel
702
857
  for (let i = 0; i < parallelResults.length; i++) {
703
858
  const settledResult = parallelResults[i];
704
859
  const toolCall = lastMessage.toolCalls[i];
860
+ const toolArgs = JSON.parse(toolCall.function.arguments);
705
861
  if (settledResult.status === 'fulfilled') {
706
862
  const result = settledResult.value;
863
+ if (result.toolResult?.success) {
864
+ // Transition to completed state
865
+ const completedState = {
866
+ attachments: result.toolResult.processedOutput.attachments,
867
+ input: toolArgs,
868
+ metadata: result.toolResult.metadata,
869
+ output: result.toolResult.processedOutput.content,
870
+ status: 'completed',
871
+ time: { end: endTime, start: startTime },
872
+ title: result.toolResult.processedOutput.title,
873
+ };
874
+ this.contextManager.updateToolCallState(toolCall.id, completedState);
875
+ }
876
+ else {
877
+ // Transition to error state
878
+ const errorState = {
879
+ error: result.toolResult?.processedOutput.content ?? result.error ?? 'Unknown error',
880
+ input: toolArgs,
881
+ status: 'error',
882
+ time: { end: endTime, start: startTime },
883
+ };
884
+ this.contextManager.updateToolCallState(toolCall.id, errorState);
885
+ }
886
+ // Also add to context as tool result message (for backward compatibility)
707
887
  // eslint-disable-next-line no-await-in-loop -- Must add results in order
708
888
  await this.addParallelToolResultToContext(result);
709
889
  }
710
890
  else {
711
- // Handle unexpected Promise rejection (should be rare since executeToolCallParallel catches errors)
891
+ // Handle unexpected Promise rejection
712
892
  const errorMessage = getErrorMessage(settledResult.reason);
713
893
  this.logger.error('Unexpected error in parallel tool execution', {
714
894
  error: settledResult.reason,
715
895
  toolCallId: toolCall.id,
716
896
  toolName: toolCall.function.name,
717
897
  });
898
+ // Transition to error state
899
+ const errorState = {
900
+ error: errorMessage,
901
+ input: toolArgs,
902
+ status: 'error',
903
+ time: { end: endTime, start: startTime },
904
+ };
905
+ this.contextManager.updateToolCallState(toolCall.id, errorState);
906
+ // Also add to context as tool result message (for backward compatibility)
718
907
  // eslint-disable-next-line no-await-in-loop -- Must add results in order
719
908
  await this.contextManager.addToolResult(toolCall.id, toolCall.function.name, `Error: ${errorMessage}`, {
720
909
  errorType: 'UNEXPECTED_ERROR',
@@ -723,4 +912,38 @@ export class ByteRoverLLMService {
723
912
  }
724
913
  }
725
914
  }
915
+ /**
916
+ * Validate LLM configuration using Zod schema.
917
+ *
918
+ * Performs validation against the centralized LLM config schema.
919
+ * Logs warnings for invalid configurations but doesn't throw to maintain
920
+ * backward compatibility with existing code.
921
+ *
922
+ * @param model - Model name to validate
923
+ * @param maxInputTokens - Optional max input tokens to validate
924
+ */
925
+ validateConfig(model, maxInputTokens) {
926
+ const result = safeParseLLMConfig({
927
+ maxInputTokens,
928
+ maxIterations: this.config?.maxIterations ?? 50,
929
+ model,
930
+ provider: this.providerType,
931
+ });
932
+ if (!result.success) {
933
+ // Log validation warnings but don't throw (backward compatibility)
934
+ const issues = result.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`).join('; ');
935
+ this.logger.warn('LLM config validation warning', {
936
+ issues,
937
+ model,
938
+ provider: this.providerType,
939
+ });
940
+ // Also check if model is valid in registry
941
+ if (!isValidProviderModel(this.providerType, model)) {
942
+ this.logger.info('Model not in registry, using fallback defaults', {
943
+ model,
944
+ provider: this.providerType,
945
+ });
946
+ }
947
+ }
948
+ }
726
949
  }
@@ -4,7 +4,7 @@ import type { IHistoryStorage } from '../../../core/interfaces/cipher/i-history-
4
4
  import type { ILLMService } from '../../../core/interfaces/cipher/i-llm-service.js';
5
5
  import type { ILogger } from '../../../core/interfaces/cipher/i-logger.js';
6
6
  import type { MemoryManager } from '../memory/memory-manager.js';
7
- import type { SimplePromptFactory } from '../system-prompt/simple-prompt-factory.js';
7
+ import type { SystemPromptManager } from '../system-prompt/system-prompt-manager.js';
8
8
  import type { ToolManager } from '../tools/tool-manager.js';
9
9
  import { SessionEventBus } from '../events/event-emitter.js';
10
10
  import { ContextManager, type FileData, type ImageData } from './context/context-manager.js';
@@ -58,8 +58,8 @@ export declare class OpenRouterLLMService implements ILLMService {
58
58
  private readonly formatter;
59
59
  private readonly logger;
60
60
  private readonly memoryManager?;
61
- private readonly promptFactory;
62
61
  private readonly sessionEventBus;
62
+ private readonly systemPromptManager;
63
63
  private readonly tokenizer;
64
64
  private readonly toolManager;
65
65
  /**
@@ -80,7 +80,7 @@ export declare class OpenRouterLLMService implements ILLMService {
80
80
  logger?: ILogger;
81
81
  memoryManager?: MemoryManager;
82
82
  sessionEventBus: SessionEventBus;
83
- systemPromptManager: SimplePromptFactory;
83
+ systemPromptManager: SystemPromptManager;
84
84
  toolManager: ToolManager;
85
85
  });
86
86
  /**
@@ -93,23 +93,22 @@ export declare class OpenRouterLLMService implements ILLMService {
93
93
  * 3. Returning final response when no more tool calls
94
94
  *
95
95
  * @param textInput - User input text
96
- * @param sessionId - Session ID for tracking the conversation
97
96
  * @param options - Execution options
98
97
  * @param options.signal - Optional abort signal for cancellation
99
98
  * @param options.imageData - Optional image data
100
99
  * @param options.fileData - Optional file data
101
100
  * @param options.stream - Whether to stream response (not implemented yet)
102
101
  * @param options.executionContext - Optional execution context (for JSON input mode, etc.)
103
- * @param options.mode - Optional mode for system prompt ('json-input' enables autonomous mode)
102
+ * @param options.taskId - Task ID for billing tracking
104
103
  * @returns Final assistant response
105
104
  */
106
- completeTask(textInput: string, sessionId: string, options?: {
105
+ completeTask(textInput: string, options?: {
107
106
  executionContext?: ExecutionContext;
108
107
  fileData?: FileData;
109
108
  imageData?: ImageData;
110
- mode?: 'autonomous' | 'default' | 'query';
111
109
  signal?: AbortSignal;
112
110
  stream?: boolean;
111
+ taskId?: string;
113
112
  }): Promise<string>;
114
113
  /**
115
114
  * Get all available tools from ToolManager.
@@ -144,7 +143,6 @@ export declare class OpenRouterLLMService implements ILLMService {
144
143
  * @param iterationCount - Current iteration number
145
144
  * @param tools - Available tools for this iteration
146
145
  * @param executionContext - Optional execution context
147
- * @param mode - Optional mode for system prompt
148
146
  * @returns Final response string if complete, null if more iterations needed
149
147
  */
150
148
  private executeAgenticIteration;