@build-astron-co/nimbus 0.4.2 → 0.4.3

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 (430) hide show
  1. package/dist/src/agent/compaction-agent.js +24 -12
  2. package/dist/src/agent/context-manager.js +2 -1
  3. package/dist/src/agent/expand-files.js +2 -1
  4. package/dist/src/agent/loop.js +71 -33
  5. package/dist/src/agent/permissions.js +4 -2
  6. package/dist/src/agent/system-prompt.js +34 -17
  7. package/dist/src/app.js +1 -1
  8. package/dist/src/auth/keychain.js +8 -4
  9. package/dist/src/auth/store.js +70 -107
  10. package/dist/src/cli/init.js +35 -19
  11. package/dist/src/cli/run.js +18 -10
  12. package/dist/src/cli/serve.js +4 -2
  13. package/dist/src/cli.js +52 -11
  14. package/dist/src/commands/alias.js +5 -3
  15. package/dist/src/commands/audit/index.js +2 -1
  16. package/dist/src/commands/aws-terraform.js +36 -18
  17. package/dist/src/commands/completions.js +1 -1
  18. package/dist/src/commands/config.js +3 -2
  19. package/dist/src/commands/connect-github.js +92 -0
  20. package/dist/src/commands/cost/index.js +3 -2
  21. package/dist/src/commands/deploy.js +15 -10
  22. package/dist/src/commands/doctor.js +6 -3
  23. package/dist/src/commands/drift/index.js +2 -1
  24. package/dist/src/commands/export.js +5 -3
  25. package/dist/src/commands/generate-terraform.js +110 -2
  26. package/dist/src/commands/import.js +3 -3
  27. package/dist/src/commands/incident.js +10 -5
  28. package/dist/src/commands/login.js +8 -93
  29. package/dist/src/commands/logs.js +16 -8
  30. package/dist/src/commands/onboarding.js +6 -4
  31. package/dist/src/commands/pipeline.js +6 -3
  32. package/dist/src/commands/plugin.js +3 -2
  33. package/dist/src/commands/profile.js +27 -14
  34. package/dist/src/commands/questionnaire.js +1 -1
  35. package/dist/src/commands/rollback.js +3 -2
  36. package/dist/src/commands/rollout.js +5 -3
  37. package/dist/src/commands/runbook.js +17 -10
  38. package/dist/src/commands/schedule.js +10 -5
  39. package/dist/src/commands/status.js +2 -1
  40. package/dist/src/commands/team-context.js +12 -7
  41. package/dist/src/commands/template.js +1 -1
  42. package/dist/src/commands/tf/index.js +6 -3
  43. package/dist/src/commands/version.js +6 -3
  44. package/dist/src/commands/watch.js +6 -3
  45. package/dist/src/compat/sqlite.js +5 -3
  46. package/dist/src/config/mode-store.js +2 -1
  47. package/dist/src/config/profiles.js +4 -2
  48. package/dist/src/config/types.js +2 -1
  49. package/dist/src/engine/executor.js +8 -4
  50. package/dist/src/engine/planner.js +9 -5
  51. package/dist/src/llm/providers/anthropic.js +6 -3
  52. package/dist/src/llm/providers/ollama.js +1 -1
  53. package/dist/src/llm/router.js +22 -7
  54. package/dist/src/sessions/manager.js +6 -3
  55. package/dist/src/sharing/viewer.js +2 -1
  56. package/dist/src/tools/file-ops.js +1 -2
  57. package/dist/src/tools/schemas/devops.js +197 -108
  58. package/dist/src/tools/schemas/standard.js +1 -1
  59. package/dist/src/ui/App.js +25 -13
  60. package/dist/src/ui/FileDiffModal.js +22 -11
  61. package/dist/src/ui/HelpModal.js +2 -1
  62. package/dist/src/ui/InputBox.js +6 -3
  63. package/dist/src/ui/MessageList.js +40 -20
  64. package/dist/src/ui/TerminalPane.js +2 -1
  65. package/dist/src/ui/ToolCallDisplay.js +12 -6
  66. package/dist/src/ui/TreePane.js +2 -1
  67. package/dist/src/ui/ink/index.js +37 -21
  68. package/dist/src/watcher/index.js +8 -4
  69. package/package.json +3 -5
  70. package/src/__tests__/alias.test.ts +0 -133
  71. package/src/__tests__/app.test.ts +0 -76
  72. package/src/__tests__/audit.test.ts +0 -877
  73. package/src/__tests__/circuit-breaker.test.ts +0 -116
  74. package/src/__tests__/cli-run.test.ts +0 -351
  75. package/src/__tests__/compat-sqlite.test.ts +0 -68
  76. package/src/__tests__/context-manager.test.ts +0 -632
  77. package/src/__tests__/context.test.ts +0 -242
  78. package/src/__tests__/devops-terminal-gaps.test.ts +0 -718
  79. package/src/__tests__/doctor.test.ts +0 -48
  80. package/src/__tests__/enterprise.test.ts +0 -401
  81. package/src/__tests__/export.test.ts +0 -236
  82. package/src/__tests__/gap-11-18-20.test.ts +0 -958
  83. package/src/__tests__/generator.test.ts +0 -433
  84. package/src/__tests__/helm-streaming.test.ts +0 -127
  85. package/src/__tests__/hooks.test.ts +0 -582
  86. package/src/__tests__/incident.test.ts +0 -179
  87. package/src/__tests__/init.test.ts +0 -487
  88. package/src/__tests__/intent-parser.test.ts +0 -229
  89. package/src/__tests__/llm-router.test.ts +0 -209
  90. package/src/__tests__/logs.test.ts +0 -107
  91. package/src/__tests__/loop-errors.test.ts +0 -244
  92. package/src/__tests__/lsp.test.ts +0 -293
  93. package/src/__tests__/modes.test.ts +0 -336
  94. package/src/__tests__/perf-optimizations.test.ts +0 -847
  95. package/src/__tests__/permissions.test.ts +0 -338
  96. package/src/__tests__/pipeline.test.ts +0 -50
  97. package/src/__tests__/polish-phase3.test.ts +0 -340
  98. package/src/__tests__/profile.test.ts +0 -237
  99. package/src/__tests__/rollback.test.ts +0 -83
  100. package/src/__tests__/runbook.test.ts +0 -219
  101. package/src/__tests__/schedule.test.ts +0 -206
  102. package/src/__tests__/serve.test.ts +0 -275
  103. package/src/__tests__/sessions.test.ts +0 -322
  104. package/src/__tests__/sharing.test.ts +0 -340
  105. package/src/__tests__/snapshots.test.ts +0 -581
  106. package/src/__tests__/standalone-migration.test.ts +0 -199
  107. package/src/__tests__/state-db.test.ts +0 -334
  108. package/src/__tests__/status.test.ts +0 -158
  109. package/src/__tests__/stream-with-tools.test.ts +0 -778
  110. package/src/__tests__/subagents.test.ts +0 -176
  111. package/src/__tests__/system-prompt.test.ts +0 -248
  112. package/src/__tests__/terminal-gap-v2.test.ts +0 -395
  113. package/src/__tests__/terminal-parity.test.ts +0 -393
  114. package/src/__tests__/tf-apply.test.ts +0 -187
  115. package/src/__tests__/tool-converter.test.ts +0 -256
  116. package/src/__tests__/tool-schemas.test.ts +0 -602
  117. package/src/__tests__/tools.test.ts +0 -144
  118. package/src/__tests__/version-json.test.ts +0 -184
  119. package/src/__tests__/version.test.ts +0 -49
  120. package/src/__tests__/watch.test.ts +0 -129
  121. package/src/agent/compaction-agent.ts +0 -266
  122. package/src/agent/context-manager.ts +0 -499
  123. package/src/agent/context.ts +0 -427
  124. package/src/agent/deploy-preview.ts +0 -487
  125. package/src/agent/expand-files.ts +0 -108
  126. package/src/agent/index.ts +0 -68
  127. package/src/agent/loop.ts +0 -1998
  128. package/src/agent/modes.ts +0 -429
  129. package/src/agent/permissions.ts +0 -513
  130. package/src/agent/subagents/base.ts +0 -116
  131. package/src/agent/subagents/cost.ts +0 -51
  132. package/src/agent/subagents/explore.ts +0 -42
  133. package/src/agent/subagents/general.ts +0 -54
  134. package/src/agent/subagents/index.ts +0 -102
  135. package/src/agent/subagents/infra.ts +0 -59
  136. package/src/agent/subagents/security.ts +0 -69
  137. package/src/agent/system-prompt.ts +0 -990
  138. package/src/app.ts +0 -180
  139. package/src/audit/activity-log.ts +0 -290
  140. package/src/audit/compliance-checker.ts +0 -540
  141. package/src/audit/cost-tracker.ts +0 -318
  142. package/src/audit/index.ts +0 -23
  143. package/src/audit/security-scanner.ts +0 -641
  144. package/src/auth/guard.ts +0 -75
  145. package/src/auth/index.ts +0 -56
  146. package/src/auth/keychain.ts +0 -82
  147. package/src/auth/oauth.ts +0 -465
  148. package/src/auth/providers.ts +0 -470
  149. package/src/auth/sso.ts +0 -113
  150. package/src/auth/store.ts +0 -505
  151. package/src/auth/types.ts +0 -187
  152. package/src/build.ts +0 -141
  153. package/src/cli/index.ts +0 -16
  154. package/src/cli/init.ts +0 -1227
  155. package/src/cli/openapi-spec.ts +0 -356
  156. package/src/cli/run.ts +0 -628
  157. package/src/cli/serve-auth.ts +0 -80
  158. package/src/cli/serve.ts +0 -539
  159. package/src/cli/web.ts +0 -71
  160. package/src/cli.ts +0 -1728
  161. package/src/clients/core-engine-client.ts +0 -227
  162. package/src/clients/enterprise-client.ts +0 -334
  163. package/src/clients/generator-client.ts +0 -351
  164. package/src/clients/git-client.ts +0 -627
  165. package/src/clients/github-client.ts +0 -410
  166. package/src/clients/helm-client.ts +0 -504
  167. package/src/clients/index.ts +0 -80
  168. package/src/clients/k8s-client.ts +0 -497
  169. package/src/clients/llm-client.ts +0 -161
  170. package/src/clients/rest-client.ts +0 -130
  171. package/src/clients/service-discovery.ts +0 -38
  172. package/src/clients/terraform-client.ts +0 -482
  173. package/src/clients/tools-client.ts +0 -1843
  174. package/src/clients/ws-client.ts +0 -115
  175. package/src/commands/alias.ts +0 -100
  176. package/src/commands/analyze/index.ts +0 -352
  177. package/src/commands/apply/helm.ts +0 -473
  178. package/src/commands/apply/index.ts +0 -213
  179. package/src/commands/apply/k8s.ts +0 -454
  180. package/src/commands/apply/terraform.ts +0 -582
  181. package/src/commands/ask.ts +0 -167
  182. package/src/commands/audit/index.ts +0 -357
  183. package/src/commands/auth-cloud.ts +0 -407
  184. package/src/commands/auth-list.ts +0 -134
  185. package/src/commands/auth-profile.ts +0 -121
  186. package/src/commands/auth-refresh.ts +0 -187
  187. package/src/commands/auth-status.ts +0 -141
  188. package/src/commands/aws/ec2.ts +0 -501
  189. package/src/commands/aws/iam.ts +0 -397
  190. package/src/commands/aws/index.ts +0 -133
  191. package/src/commands/aws/lambda.ts +0 -396
  192. package/src/commands/aws/rds.ts +0 -439
  193. package/src/commands/aws/s3.ts +0 -439
  194. package/src/commands/aws/vpc.ts +0 -393
  195. package/src/commands/aws-discover.ts +0 -542
  196. package/src/commands/aws-terraform.ts +0 -755
  197. package/src/commands/azure/aks.ts +0 -376
  198. package/src/commands/azure/functions.ts +0 -253
  199. package/src/commands/azure/index.ts +0 -116
  200. package/src/commands/azure/storage.ts +0 -478
  201. package/src/commands/azure/vm.ts +0 -355
  202. package/src/commands/billing/index.ts +0 -256
  203. package/src/commands/chat.ts +0 -320
  204. package/src/commands/completions.ts +0 -268
  205. package/src/commands/config.ts +0 -372
  206. package/src/commands/cost/cloud-cost-estimator.ts +0 -266
  207. package/src/commands/cost/estimator.ts +0 -79
  208. package/src/commands/cost/index.ts +0 -810
  209. package/src/commands/cost/parsers/terraform.ts +0 -273
  210. package/src/commands/cost/parsers/types.ts +0 -25
  211. package/src/commands/cost/pricing/aws.ts +0 -544
  212. package/src/commands/cost/pricing/azure.ts +0 -499
  213. package/src/commands/cost/pricing/gcp.ts +0 -396
  214. package/src/commands/cost/pricing/index.ts +0 -40
  215. package/src/commands/demo.ts +0 -250
  216. package/src/commands/deploy.ts +0 -260
  217. package/src/commands/doctor.ts +0 -1386
  218. package/src/commands/drift/index.ts +0 -787
  219. package/src/commands/explain.ts +0 -277
  220. package/src/commands/export.ts +0 -146
  221. package/src/commands/feedback.ts +0 -389
  222. package/src/commands/fix.ts +0 -324
  223. package/src/commands/fs/index.ts +0 -402
  224. package/src/commands/gcp/compute.ts +0 -325
  225. package/src/commands/gcp/functions.ts +0 -271
  226. package/src/commands/gcp/gke.ts +0 -438
  227. package/src/commands/gcp/iam.ts +0 -344
  228. package/src/commands/gcp/index.ts +0 -129
  229. package/src/commands/gcp/storage.ts +0 -284
  230. package/src/commands/generate-helm.ts +0 -1249
  231. package/src/commands/generate-k8s.ts +0 -1508
  232. package/src/commands/generate-terraform.ts +0 -1202
  233. package/src/commands/gh/index.ts +0 -863
  234. package/src/commands/git/index.ts +0 -1343
  235. package/src/commands/helm/index.ts +0 -1126
  236. package/src/commands/help.ts +0 -715
  237. package/src/commands/history.ts +0 -149
  238. package/src/commands/import.ts +0 -868
  239. package/src/commands/incident.ts +0 -166
  240. package/src/commands/index.ts +0 -367
  241. package/src/commands/init.ts +0 -1051
  242. package/src/commands/k8s/index.ts +0 -1137
  243. package/src/commands/login.ts +0 -716
  244. package/src/commands/logout.ts +0 -83
  245. package/src/commands/logs.ts +0 -167
  246. package/src/commands/onboarding.ts +0 -405
  247. package/src/commands/pipeline.ts +0 -186
  248. package/src/commands/plan/display.ts +0 -279
  249. package/src/commands/plan/index.ts +0 -599
  250. package/src/commands/plugin.ts +0 -398
  251. package/src/commands/preview.ts +0 -452
  252. package/src/commands/profile.ts +0 -342
  253. package/src/commands/questionnaire.ts +0 -1172
  254. package/src/commands/resume.ts +0 -47
  255. package/src/commands/rollback.ts +0 -315
  256. package/src/commands/rollout.ts +0 -88
  257. package/src/commands/runbook.ts +0 -346
  258. package/src/commands/schedule.ts +0 -236
  259. package/src/commands/status.ts +0 -252
  260. package/src/commands/team/index.ts +0 -346
  261. package/src/commands/team-context.ts +0 -220
  262. package/src/commands/template.ts +0 -233
  263. package/src/commands/tf/index.ts +0 -1093
  264. package/src/commands/upgrade.ts +0 -609
  265. package/src/commands/usage/index.ts +0 -134
  266. package/src/commands/version.ts +0 -174
  267. package/src/commands/watch.ts +0 -153
  268. package/src/compat/index.ts +0 -2
  269. package/src/compat/runtime.ts +0 -12
  270. package/src/compat/sqlite.ts +0 -177
  271. package/src/config/index.ts +0 -17
  272. package/src/config/manager.ts +0 -530
  273. package/src/config/mode-store.ts +0 -62
  274. package/src/config/profiles.ts +0 -84
  275. package/src/config/safety-policy.ts +0 -358
  276. package/src/config/schema.ts +0 -125
  277. package/src/config/types.ts +0 -609
  278. package/src/config/workspace-state.ts +0 -53
  279. package/src/context/context-db.ts +0 -199
  280. package/src/demo/index.ts +0 -349
  281. package/src/demo/scenarios/full-journey.ts +0 -229
  282. package/src/demo/scenarios/getting-started.ts +0 -127
  283. package/src/demo/scenarios/helm-release.ts +0 -341
  284. package/src/demo/scenarios/k8s-deployment.ts +0 -194
  285. package/src/demo/scenarios/terraform-vpc.ts +0 -170
  286. package/src/demo/types.ts +0 -92
  287. package/src/engine/cost-estimator.ts +0 -480
  288. package/src/engine/diagram-generator.ts +0 -256
  289. package/src/engine/drift-detector.ts +0 -902
  290. package/src/engine/executor.ts +0 -1066
  291. package/src/engine/index.ts +0 -76
  292. package/src/engine/orchestrator.ts +0 -636
  293. package/src/engine/planner.ts +0 -787
  294. package/src/engine/safety.ts +0 -743
  295. package/src/engine/verifier.ts +0 -770
  296. package/src/enterprise/audit.ts +0 -348
  297. package/src/enterprise/auth.ts +0 -270
  298. package/src/enterprise/billing.ts +0 -822
  299. package/src/enterprise/index.ts +0 -17
  300. package/src/enterprise/teams.ts +0 -443
  301. package/src/generator/best-practices.ts +0 -1608
  302. package/src/generator/helm.ts +0 -630
  303. package/src/generator/index.ts +0 -37
  304. package/src/generator/intent-parser.ts +0 -514
  305. package/src/generator/kubernetes.ts +0 -976
  306. package/src/generator/terraform.ts +0 -1875
  307. package/src/history/index.ts +0 -8
  308. package/src/history/manager.ts +0 -250
  309. package/src/history/types.ts +0 -34
  310. package/src/hooks/config.ts +0 -432
  311. package/src/hooks/engine.ts +0 -392
  312. package/src/hooks/index.ts +0 -4
  313. package/src/llm/auth-bridge.ts +0 -198
  314. package/src/llm/circuit-breaker.ts +0 -140
  315. package/src/llm/config-loader.ts +0 -201
  316. package/src/llm/cost-calculator.ts +0 -171
  317. package/src/llm/index.ts +0 -8
  318. package/src/llm/model-aliases.ts +0 -115
  319. package/src/llm/provider-registry.ts +0 -63
  320. package/src/llm/providers/anthropic.ts +0 -462
  321. package/src/llm/providers/bedrock.ts +0 -477
  322. package/src/llm/providers/google.ts +0 -405
  323. package/src/llm/providers/ollama.ts +0 -767
  324. package/src/llm/providers/openai-compatible.ts +0 -340
  325. package/src/llm/providers/openai.ts +0 -328
  326. package/src/llm/providers/openrouter.ts +0 -338
  327. package/src/llm/router.ts +0 -1104
  328. package/src/llm/types.ts +0 -232
  329. package/src/lsp/client.ts +0 -298
  330. package/src/lsp/languages.ts +0 -119
  331. package/src/lsp/manager.ts +0 -294
  332. package/src/mcp/client.ts +0 -402
  333. package/src/mcp/index.ts +0 -5
  334. package/src/mcp/manager.ts +0 -133
  335. package/src/nimbus.ts +0 -234
  336. package/src/plugins/index.ts +0 -27
  337. package/src/plugins/loader.ts +0 -334
  338. package/src/plugins/manager.ts +0 -376
  339. package/src/plugins/types.ts +0 -284
  340. package/src/scanners/cicd-scanner.ts +0 -258
  341. package/src/scanners/cloud-scanner.ts +0 -466
  342. package/src/scanners/framework-scanner.ts +0 -469
  343. package/src/scanners/iac-scanner.ts +0 -388
  344. package/src/scanners/index.ts +0 -539
  345. package/src/scanners/language-scanner.ts +0 -276
  346. package/src/scanners/package-manager-scanner.ts +0 -277
  347. package/src/scanners/types.ts +0 -172
  348. package/src/sessions/manager.ts +0 -472
  349. package/src/sessions/types.ts +0 -44
  350. package/src/sharing/sync.ts +0 -300
  351. package/src/sharing/viewer.ts +0 -163
  352. package/src/snapshots/index.ts +0 -2
  353. package/src/snapshots/manager.ts +0 -530
  354. package/src/state/artifacts.ts +0 -147
  355. package/src/state/audit.ts +0 -137
  356. package/src/state/billing.ts +0 -240
  357. package/src/state/checkpoints.ts +0 -117
  358. package/src/state/config.ts +0 -67
  359. package/src/state/conversations.ts +0 -14
  360. package/src/state/credentials.ts +0 -154
  361. package/src/state/db.ts +0 -58
  362. package/src/state/index.ts +0 -26
  363. package/src/state/messages.ts +0 -115
  364. package/src/state/projects.ts +0 -123
  365. package/src/state/schema.ts +0 -236
  366. package/src/state/sessions.ts +0 -147
  367. package/src/state/teams.ts +0 -200
  368. package/src/telemetry.ts +0 -108
  369. package/src/tools/aws-ops.ts +0 -952
  370. package/src/tools/azure-ops.ts +0 -579
  371. package/src/tools/file-ops.ts +0 -615
  372. package/src/tools/gcp-ops.ts +0 -625
  373. package/src/tools/git-ops.ts +0 -773
  374. package/src/tools/github-ops.ts +0 -799
  375. package/src/tools/helm-ops.ts +0 -943
  376. package/src/tools/index.ts +0 -17
  377. package/src/tools/k8s-ops.ts +0 -819
  378. package/src/tools/schemas/converter.ts +0 -184
  379. package/src/tools/schemas/devops.ts +0 -3502
  380. package/src/tools/schemas/index.ts +0 -73
  381. package/src/tools/schemas/standard.ts +0 -1148
  382. package/src/tools/schemas/types.ts +0 -735
  383. package/src/tools/spawn-exec.ts +0 -148
  384. package/src/tools/terraform-ops.ts +0 -862
  385. package/src/types/ambient.d.ts +0 -193
  386. package/src/types/config.ts +0 -83
  387. package/src/types/drift.ts +0 -116
  388. package/src/types/enterprise.ts +0 -335
  389. package/src/types/index.ts +0 -20
  390. package/src/types/plan.ts +0 -44
  391. package/src/types/request.ts +0 -65
  392. package/src/types/response.ts +0 -54
  393. package/src/types/service.ts +0 -51
  394. package/src/ui/App.tsx +0 -2114
  395. package/src/ui/DeployPreview.tsx +0 -174
  396. package/src/ui/FileDiffModal.tsx +0 -162
  397. package/src/ui/Header.tsx +0 -131
  398. package/src/ui/HelpModal.tsx +0 -57
  399. package/src/ui/InputBox.tsx +0 -503
  400. package/src/ui/MessageList.tsx +0 -1032
  401. package/src/ui/PermissionPrompt.tsx +0 -163
  402. package/src/ui/StatusBar.tsx +0 -277
  403. package/src/ui/TerminalPane.tsx +0 -84
  404. package/src/ui/ToolCallDisplay.tsx +0 -643
  405. package/src/ui/TreePane.tsx +0 -132
  406. package/src/ui/chat-ui.ts +0 -850
  407. package/src/ui/index.ts +0 -33
  408. package/src/ui/ink/index.ts +0 -1444
  409. package/src/ui/streaming.ts +0 -176
  410. package/src/ui/theme.ts +0 -104
  411. package/src/ui/types.ts +0 -75
  412. package/src/utils/analytics.ts +0 -72
  413. package/src/utils/cost-warning.ts +0 -27
  414. package/src/utils/env.ts +0 -46
  415. package/src/utils/errors.ts +0 -69
  416. package/src/utils/event-bus.ts +0 -38
  417. package/src/utils/index.ts +0 -24
  418. package/src/utils/logger.ts +0 -171
  419. package/src/utils/rate-limiter.ts +0 -121
  420. package/src/utils/service-auth.ts +0 -49
  421. package/src/utils/validation.ts +0 -53
  422. package/src/version.ts +0 -4
  423. package/src/watcher/index.ts +0 -214
  424. package/src/wizard/approval.ts +0 -383
  425. package/src/wizard/index.ts +0 -25
  426. package/src/wizard/prompts.ts +0 -338
  427. package/src/wizard/types.ts +0 -172
  428. package/src/wizard/ui.ts +0 -556
  429. package/src/wizard/wizard.ts +0 -304
  430. package/tsconfig.json +0 -24
@@ -1,499 +0,0 @@
1
- /**
2
- * Context Manager — Token Tracking & Auto-Compact
3
- *
4
- * Tracks cumulative token usage across the agent loop and triggers
5
- * automatic context compaction when usage exceeds a configurable
6
- * threshold (default 85% of the model's context window).
7
- *
8
- * The manager provides:
9
- * - Token estimation for messages, system prompts, and tool definitions.
10
- * - A breakdown of how the context budget is being consumed.
11
- * - Message selection logic for deciding what to preserve vs. summarize.
12
- * - A builder for reassembling messages after compaction.
13
- *
14
- * Configuration can be supplied via constructor options or read from the
15
- * Nimbus config database (keys: `context.auto_compact_threshold`,
16
- * `context.max_file_injection`).
17
- *
18
- * @module agent/context-manager
19
- */
20
-
21
- import { getTextContent, type LLMMessage } from '../llm/types';
22
- import { getConfig } from '../state/config';
23
-
24
- // ---------------------------------------------------------------------------
25
- // Public Types
26
- // ---------------------------------------------------------------------------
27
-
28
- /** Detailed breakdown of how the context window budget is being used. */
29
- export interface ContextBreakdown {
30
- /** Tokens consumed by the base system prompt (excluding NIMBUS.md). */
31
- systemPrompt: number;
32
- /** Tokens consumed by NIMBUS.md instructions within the system prompt. */
33
- nimbusInstructions: number;
34
- /** Tokens consumed by all conversation messages. */
35
- messages: number;
36
- /** Tokens consumed by tool definition schemas. */
37
- toolDefinitions: number;
38
- /** Sum of all token categories. */
39
- total: number;
40
- /** Total available budget (model context window size). */
41
- budget: number;
42
- /** Percentage of budget currently in use (0-100). */
43
- usagePercent: number;
44
- }
45
-
46
- /** Result of a compaction operation. */
47
- export interface CompactionResult {
48
- /** Token count of the messages that were summarized. */
49
- originalTokens: number;
50
- /** Token count of the compacted message array. */
51
- compactedTokens: number;
52
- /** Tokens saved by compaction (originalTokens - summary tokens). */
53
- savedTokens: number;
54
- /** Whether a proper LLM summary was produced (false = fallback used). */
55
- summaryPreserved: boolean;
56
- }
57
-
58
- /** Configuration options for the context manager. */
59
- export interface ContextManagerOptions {
60
- /** Max context window tokens (default: auto-detected from model, fallback 200000). */
61
- maxContextTokens?: number;
62
- /** Model identifier — used to auto-detect context window size. */
63
- model?: string;
64
- /** Threshold percentage to trigger auto-compact (0.0 - 1.0, default: 0.85). */
65
- autoCompactThreshold?: number;
66
- /** Number of recent messages to always preserve during compaction (default: 5). */
67
- preserveRecentMessages?: number;
68
- /** NIMBUS.md section keys that should always remain in context. */
69
- alwaysInContext?: string[];
70
- }
71
-
72
- // ---------------------------------------------------------------------------
73
- // Per-Model Context Window Sizes
74
- // ---------------------------------------------------------------------------
75
-
76
- /**
77
- * Known context window sizes (in tokens) for popular models.
78
- *
79
- * When a model is not listed here, the manager falls back to the
80
- * `maxContextTokens` option (default: 200 000).
81
- */
82
- const MODEL_CONTEXT_WINDOWS: Record<string, number> = {
83
- // Anthropic
84
- 'claude-opus-4-20250514': 200_000,
85
- 'claude-sonnet-4-20250514': 200_000,
86
- 'claude-haiku-4-20250514': 200_000,
87
- 'claude-3-5-sonnet-20241022': 200_000,
88
- 'claude-3-5-haiku-20241022': 200_000,
89
- 'claude-3-opus-20240229': 200_000,
90
- 'claude-3-sonnet-20240229': 200_000,
91
- 'claude-3-haiku-20240307': 200_000,
92
-
93
- // OpenAI
94
- 'gpt-4o': 128_000,
95
- 'gpt-4o-mini': 128_000,
96
- 'gpt-4-turbo': 128_000,
97
- 'gpt-4': 8_192,
98
- 'gpt-3.5-turbo': 16_385,
99
- o1: 200_000,
100
- 'o1-mini': 128_000,
101
- 'o1-preview': 128_000,
102
- 'o3-mini': 200_000,
103
-
104
- // Google
105
- 'gemini-2.0-flash-exp': 1_048_576,
106
- 'gemini-1.5-pro': 2_097_152,
107
- 'gemini-1.5-flash': 1_048_576,
108
-
109
- // Groq (Llama)
110
- 'llama-3.1-70b-versatile': 131_072,
111
- 'llama-3.1-8b-instant': 131_072,
112
- 'llama-3.3-70b-versatile': 131_072,
113
-
114
- // DeepSeek
115
- 'deepseek-chat': 64_000,
116
- 'deepseek-coder': 64_000,
117
- 'deepseek-reasoner': 64_000,
118
-
119
- // Local (Ollama defaults — dynamic lookup can override)
120
- 'llama3.2': 128_000,
121
- mistral: 32_768,
122
- codellama: 16_384,
123
- };
124
-
125
- /**
126
- * Look up the context window size for a model identifier.
127
- *
128
- * Tries exact match first, then prefix match (for versioned model IDs
129
- * like `claude-sonnet-4-20250514`), then returns `null` if unknown.
130
- */
131
- export function getModelContextWindow(model: string): number | null {
132
- // Exact match
133
- if (MODEL_CONTEXT_WINDOWS[model] !== undefined) {
134
- return MODEL_CONTEXT_WINDOWS[model];
135
- }
136
-
137
- // Prefix match: e.g., "gpt-4o-2024-08-06" should match "gpt-4o"
138
- for (const [key, value] of Object.entries(MODEL_CONTEXT_WINDOWS)) {
139
- if (model.startsWith(key)) {
140
- return value;
141
- }
142
- }
143
-
144
- return null;
145
- }
146
-
147
- // ---------------------------------------------------------------------------
148
- // Token Estimation Utilities
149
- // ---------------------------------------------------------------------------
150
-
151
- /**
152
- * Rough token estimate based on character count.
153
- *
154
- * Uses the common heuristic of ~4 characters per token, which is a
155
- * reasonable average across English text and source code.
156
- *
157
- * @param text - The text to estimate.
158
- * @returns Approximate token count (rounded up).
159
- */
160
- export function estimateTokens(text: string): number {
161
- return Math.ceil(text.length / 4);
162
- }
163
-
164
- /**
165
- * Estimate token count for a single LLM message.
166
- *
167
- * Accounts for the message content, structural overhead (role, framing),
168
- * and any tool calls embedded in the message.
169
- *
170
- * @param message - The LLM message to estimate.
171
- * @returns Approximate token count.
172
- */
173
- export function estimateMessageTokens(message: LLMMessage): number {
174
- let tokens = 0;
175
-
176
- tokens += estimateTokens(getTextContent(message.content));
177
-
178
- // Add overhead for role and message structure
179
- tokens += 4;
180
-
181
- // Tool calls add extra tokens for name, arguments, and JSON structure
182
- if (message.toolCalls) {
183
- for (const tc of message.toolCalls) {
184
- tokens += estimateTokens(tc.function.name);
185
- tokens += estimateTokens(tc.function.arguments);
186
- tokens += 10; // structural overhead per tool call
187
- }
188
- }
189
-
190
- return tokens;
191
- }
192
-
193
- // ---------------------------------------------------------------------------
194
- // H2: Terraform plan output detection
195
- // ---------------------------------------------------------------------------
196
-
197
- /**
198
- * Patterns that indicate a message contains a terraform plan output.
199
- * These messages are critical context that should survive compaction.
200
- */
201
- const TERRAFORM_PLAN_INDICATORS = [
202
- 'Plan:',
203
- 'will be created',
204
- 'will be destroyed',
205
- 'to add,',
206
- 'to change,',
207
- 'to destroy',
208
- ] as const;
209
-
210
- /**
211
- * Return true if the given text content contains terraform plan output.
212
- * Used by selectPreservedMessages to protect plan results from compaction.
213
- *
214
- * @param text - The text content to inspect.
215
- * @returns `true` if the text looks like terraform plan output.
216
- */
217
- function containsTerraformPlanOutput(text: string): boolean {
218
- return TERRAFORM_PLAN_INDICATORS.some(indicator => text.includes(indicator));
219
- }
220
-
221
- // ---------------------------------------------------------------------------
222
- // ContextManager Class
223
- // ---------------------------------------------------------------------------
224
-
225
- /**
226
- * Manages context window budget and auto-compaction decisions.
227
- *
228
- * Create one instance per agent session. The manager does not hold
229
- * conversation state itself -- it operates on message arrays passed in
230
- * by the caller.
231
- */
232
- export class ContextManager {
233
- private maxContextTokens: number;
234
- private autoCompactThreshold: number;
235
- private preserveRecentMessages: number;
236
- private alwaysInContext: string[];
237
- /** Per-message token count cache: key = `role:contentLen:toolCallCount:toolCallId`. */
238
- private _tokenCache: Map<string, number> = new Map();
239
-
240
- constructor(options?: ContextManagerOptions) {
241
- // Try loading from config DB, fall back to options/defaults
242
- const configThreshold = getConfigSafe('context.auto_compact_threshold');
243
-
244
- // Auto-detect context window from model if provided, then options, then default
245
- const modelWindow = options?.model ? getModelContextWindow(options.model) : null;
246
- this.maxContextTokens = options?.maxContextTokens ?? modelWindow ?? 200_000;
247
- this.autoCompactThreshold = configThreshold ?? options?.autoCompactThreshold ?? 0.85;
248
- this.preserveRecentMessages = options?.preserveRecentMessages ?? 5;
249
- this.alwaysInContext = options?.alwaysInContext ?? ['Infrastructure Context', 'Tool Timeouts'];
250
- }
251
-
252
- /**
253
- * Get cached token count for a message, computing + caching on miss.
254
- * Key encodes role + content length + tool call count + tool call IDs so
255
- * any meaningful change busts the cache entry.
256
- */
257
- private _getCachedTokens(msg: LLMMessage): number {
258
- const contentLen = typeof msg.content === 'string'
259
- ? msg.content.length
260
- : JSON.stringify(msg.content).length;
261
- const tcCount = msg.toolCalls?.length ?? 0;
262
- const tcIds = msg.toolCalls?.map(tc => tc.id).join(',') ?? '';
263
- const key = `${msg.role}:${contentLen}:${tcCount}:${tcIds}`;
264
- const cached = this._tokenCache.get(key);
265
- if (cached !== undefined) return cached;
266
- const val = estimateMessageTokens(msg);
267
- this._tokenCache.set(key, val);
268
- return val;
269
- }
270
-
271
- /** Clear the token cache. Call after compaction when old messages are removed. */
272
- clearTokenCache(): void {
273
- this._tokenCache.clear();
274
- }
275
-
276
- /**
277
- * Check whether auto-compaction should be triggered.
278
- *
279
- * Returns `true` if the estimated token usage is at or above the
280
- * configured threshold percentage of the context window.
281
- *
282
- * @param systemPrompt - The full system prompt string.
283
- * @param messages - Current conversation messages.
284
- * @param toolDefinitionsTokens - Pre-computed token count for tool schemas.
285
- * @returns `true` if compaction should run.
286
- */
287
- shouldCompact(
288
- systemPrompt: string,
289
- messages: LLMMessage[],
290
- toolDefinitionsTokens: number
291
- ): boolean {
292
- const usage = this.calculateUsage(systemPrompt, messages, toolDefinitionsTokens);
293
- return usage.usagePercent >= this.autoCompactThreshold * 100;
294
- }
295
-
296
- /**
297
- * Calculate a detailed context usage breakdown.
298
- *
299
- * Separates the system prompt into base instructions and NIMBUS.md
300
- * content (if present), and sums up messages and tool definitions
301
- * to produce a full picture of context window consumption.
302
- *
303
- * @param systemPrompt - The full system prompt string.
304
- * @param messages - Current conversation messages.
305
- * @param toolDefinitionsTokens - Pre-computed token count for tool schemas.
306
- * @returns A {@link ContextBreakdown} with per-category token counts.
307
- */
308
- calculateUsage(
309
- systemPrompt: string,
310
- messages: LLMMessage[],
311
- toolDefinitionsTokens: number
312
- ): ContextBreakdown {
313
- const systemPromptTokens = estimateTokens(systemPrompt);
314
-
315
- // Separate NIMBUS.md instructions if they appear in system prompt
316
- const nimbusMarker = '# NIMBUS.md';
317
- const nimbusIdx = systemPrompt.indexOf(nimbusMarker);
318
- let nimbusInstructionsTokens = 0;
319
- let baseSystemTokens = systemPromptTokens;
320
-
321
- if (nimbusIdx >= 0) {
322
- const nimbusContent = systemPrompt.slice(nimbusIdx);
323
- nimbusInstructionsTokens = estimateTokens(nimbusContent);
324
- baseSystemTokens = systemPromptTokens - nimbusInstructionsTokens;
325
- }
326
-
327
- const messagesTokens = messages.reduce((sum, msg) => sum + this._getCachedTokens(msg), 0);
328
-
329
- const total = systemPromptTokens + messagesTokens + toolDefinitionsTokens;
330
- const usagePercent =
331
- this.maxContextTokens > 0 ? Math.round((total / this.maxContextTokens) * 100) : 0;
332
-
333
- return {
334
- systemPrompt: baseSystemTokens,
335
- nimbusInstructions: nimbusInstructionsTokens,
336
- messages: messagesTokens,
337
- toolDefinitions: toolDefinitionsTokens,
338
- total,
339
- budget: this.maxContextTokens,
340
- usagePercent,
341
- };
342
- }
343
-
344
- /**
345
- * Select which messages to preserve during compaction.
346
- *
347
- * Preservation rules:
348
- * - The first message is always kept (initial user context).
349
- * - The last N messages are always kept (recent conversation).
350
- * - Tool messages near the recent window are kept (active tool state).
351
- * - Previous compaction summary blocks are always kept.
352
- * - H2: Tool result messages containing terraform plan output are always
353
- * kept so the agent retains critical plan context across compaction.
354
- * - Everything else is marked for summarization.
355
- *
356
- * @param messages - The full conversation message array.
357
- * @returns An object with `preserved` and `toSummarize` arrays.
358
- */
359
- selectPreservedMessages(messages: LLMMessage[]): {
360
- preserved: LLMMessage[];
361
- toSummarize: LLMMessage[];
362
- } {
363
- if (messages.length <= this.preserveRecentMessages + 1) {
364
- return { preserved: [...messages], toSummarize: [] };
365
- }
366
-
367
- const preserved: LLMMessage[] = [];
368
- const toSummarize: LLMMessage[] = [];
369
-
370
- for (let i = 0; i < messages.length; i++) {
371
- const msg = messages[i];
372
- const isFirst = i === 0;
373
- const isRecent = i >= messages.length - this.preserveRecentMessages;
374
- const hasActiveTools =
375
- msg.role === 'tool' && i >= messages.length - this.preserveRecentMessages - 2;
376
-
377
- // Always preserve summary blocks (from previous compactions)
378
- const isSummary = getTextContent(msg.content).startsWith('[Context Summary]');
379
-
380
- // H2: Always preserve messages containing terraform plan output.
381
- // These are typically `tool` role messages or `assistant` messages with
382
- // tool_use content blocks whose text contains plan output markers.
383
- const textContent = getTextContent(msg.content);
384
- const isTerraformPlan =
385
- (msg.role === 'tool' || msg.role === 'assistant') &&
386
- containsTerraformPlanOutput(textContent);
387
-
388
- if (isFirst || isRecent || hasActiveTools || isSummary || isTerraformPlan) {
389
- preserved.push(msg);
390
- } else {
391
- toSummarize.push(msg);
392
- }
393
- }
394
-
395
- return { preserved, toSummarize };
396
- }
397
-
398
- /**
399
- * Build the compacted message array by inserting a summary.
400
- *
401
- * Places the summary as a user message immediately after the first
402
- * preserved message, then appends all remaining preserved messages.
403
- * The summary is wrapped with `[Context Summary]` markers so future
404
- * compaction passes can identify and preserve it.
405
- *
406
- * @param preserved - Messages to keep verbatim.
407
- * @param summary - The LLM-generated (or fallback) summary text.
408
- * @returns A new message array ready to replace the original.
409
- */
410
- buildCompactedMessages(preserved: LLMMessage[], summary: string): LLMMessage[] {
411
- const result: LLMMessage[] = [];
412
-
413
- // Keep the first preserved message (typically the first user message)
414
- if (preserved.length > 0) {
415
- result.push(preserved[0]);
416
- }
417
-
418
- // Insert the summary as a user message with a clear marker
419
- result.push({
420
- role: 'user' as const,
421
- content: `[Context Summary] The following is a summary of the earlier conversation:\n\n${summary}\n\n---\nThe conversation continues below.`,
422
- });
423
-
424
- // Append remaining preserved messages
425
- for (let i = 1; i < preserved.length; i++) {
426
- result.push(preserved[i]);
427
- }
428
-
429
- return result;
430
- }
431
-
432
- /**
433
- * Get the current configuration values.
434
- *
435
- * Useful for displaying context status in the TUI.
436
- */
437
- getConfig(): {
438
- maxContextTokens: number;
439
- autoCompactThreshold: number;
440
- preserveRecentMessages: number;
441
- } {
442
- return {
443
- maxContextTokens: this.maxContextTokens,
444
- autoCompactThreshold: this.autoCompactThreshold,
445
- preserveRecentMessages: this.preserveRecentMessages,
446
- };
447
- }
448
-
449
- /**
450
- * Update the max context tokens.
451
- *
452
- * Call this when the model changes mid-session so the compaction
453
- * threshold adjusts to the new model's context window.
454
- *
455
- * @param tokens - The new maximum context window size.
456
- */
457
- setMaxContextTokens(tokens: number): void {
458
- this.maxContextTokens = tokens;
459
- }
460
-
461
- /**
462
- * Update the context window based on a model identifier.
463
- *
464
- * Looks up the model's known context window size. If the model is
465
- * not in the built-in map, the current budget is left unchanged.
466
- *
467
- * @param model - The model identifier (e.g., "gpt-4o", "claude-sonnet-4-20250514").
468
- * @returns `true` if the budget was updated, `false` if model is unknown.
469
- */
470
- setModel(model: string): boolean {
471
- // Strip provider prefix (e.g., "openai/gpt-4o" → "gpt-4o")
472
- const stripped = model.includes('/') ? model.split('/').slice(1).join('/') : model;
473
- const window = getModelContextWindow(stripped);
474
- if (window !== null) {
475
- this.maxContextTokens = window;
476
- return true;
477
- }
478
- return false;
479
- }
480
- }
481
-
482
- // ---------------------------------------------------------------------------
483
- // Internal Helpers
484
- // ---------------------------------------------------------------------------
485
-
486
- /**
487
- * Safely read a config value without crashing if the DB is not ready.
488
- *
489
- * During early initialization the SQLite database may not yet be open.
490
- * This wrapper catches any error and returns `null` so the constructor
491
- * can fall back to provided options or built-in defaults.
492
- */
493
- function getConfigSafe(key: string): any | null {
494
- try {
495
- return getConfig(key);
496
- } catch {
497
- return null;
498
- }
499
- }