alloy-runtime-cli 0.1.0__py3-none-any.whl

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 (451) hide show
  1. alloy_runtime_cli-0.1.0.dist-info/METADATA +61 -0
  2. alloy_runtime_cli-0.1.0.dist-info/RECORD +451 -0
  3. alloy_runtime_cli-0.1.0.dist-info/WHEEL +5 -0
  4. alloy_runtime_cli-0.1.0.dist-info/entry_points.txt +2 -0
  5. alloy_runtime_cli-0.1.0.dist-info/top_level.txt +1 -0
  6. cli/__init__.py +0 -0
  7. cli/commands/__init__.py +0 -0
  8. cli/commands/admin/__init__.py +0 -0
  9. cli/commands/admin/bootstrap_command.py +118 -0
  10. cli/commands/admin/credentials/__init__.py +0 -0
  11. cli/commands/admin/credentials/create/__init__.py +0 -0
  12. cli/commands/admin/credentials/create/command.py +148 -0
  13. cli/commands/admin/credentials/create/presenter.py +16 -0
  14. cli/commands/admin/credentials/grant/__init__.py +0 -0
  15. cli/commands/admin/credentials/grant/command.py +119 -0
  16. cli/commands/admin/credentials/grant/fields.py +33 -0
  17. cli/commands/admin/credentials/grant/presenter.py +23 -0
  18. cli/commands/agents/__init__.py +0 -0
  19. cli/commands/agents/create/__init__.py +0 -0
  20. cli/commands/agents/create/command.py +475 -0
  21. cli/commands/agents/create/fields.py +64 -0
  22. cli/commands/agents/create/presenter.py +68 -0
  23. cli/commands/agents/delete/__init__.py +0 -0
  24. cli/commands/agents/delete/command.py +47 -0
  25. cli/commands/agents/delete/presenter.py +16 -0
  26. cli/commands/agents/get/command.py +37 -0
  27. cli/commands/agents/get/presenter.py +32 -0
  28. cli/commands/agents/list/__init__.py +1 -0
  29. cli/commands/agents/list/command.py +54 -0
  30. cli/commands/agents/list/presenter.py +82 -0
  31. cli/commands/agents/update/__init__.py +0 -0
  32. cli/commands/agents/update/command.py +435 -0
  33. cli/commands/agents/update/fields.py +40 -0
  34. cli/commands/agents/update/presenter.py +68 -0
  35. cli/commands/audio/__init__.py +0 -0
  36. cli/commands/audio/transcribe/__init__.py +0 -0
  37. cli/commands/audio/transcribe/command.py +144 -0
  38. cli/commands/audio/transcribe/presenter.py +15 -0
  39. cli/commands/auth/__init__.py +0 -0
  40. cli/commands/auth/login/__init__.py +0 -0
  41. cli/commands/auth/login/command.py +80 -0
  42. cli/commands/auth/signup/__init__.py +0 -0
  43. cli/commands/auth/signup/command.py +115 -0
  44. cli/commands/billing/__init__.py +1 -0
  45. cli/commands/billing/costs/__init__.py +1 -0
  46. cli/commands/billing/costs/by_agent/__init__.py +1 -0
  47. cli/commands/billing/costs/by_agent/command.py +57 -0
  48. cli/commands/billing/costs/by_agent/presenter.py +81 -0
  49. cli/commands/billing/costs/by_model/__init__.py +1 -0
  50. cli/commands/billing/costs/by_model/command.py +57 -0
  51. cli/commands/billing/costs/by_model/presenter.py +80 -0
  52. cli/commands/billing/costs/daily/__init__.py +1 -0
  53. cli/commands/billing/costs/daily/command.py +55 -0
  54. cli/commands/billing/costs/daily/presenter.py +75 -0
  55. cli/commands/billing/costs/summary/__init__.py +1 -0
  56. cli/commands/billing/costs/summary/command.py +57 -0
  57. cli/commands/billing/costs/summary/presenter.py +42 -0
  58. cli/commands/billing/projects/__init__.py +1 -0
  59. cli/commands/billing/projects/create/__init__.py +1 -0
  60. cli/commands/billing/projects/create/command.py +60 -0
  61. cli/commands/billing/projects/create/presenter.py +26 -0
  62. cli/commands/billing/projects/get/__init__.py +1 -0
  63. cli/commands/billing/projects/get/command.py +33 -0
  64. cli/commands/billing/projects/get/presenter.py +32 -0
  65. cli/commands/billing/projects/list/__init__.py +1 -0
  66. cli/commands/billing/projects/list/command.py +40 -0
  67. cli/commands/billing/projects/list/presenter.py +57 -0
  68. cli/commands/content/__init__.py +1 -0
  69. cli/commands/content/delete/__init__.py +0 -0
  70. cli/commands/content/delete/command.py +49 -0
  71. cli/commands/content/delete/presenter.py +18 -0
  72. cli/commands/content/edit/__init__.py +1 -0
  73. cli/commands/content/edit/command.py +155 -0
  74. cli/commands/content/edit/editor.py +150 -0
  75. cli/commands/content/edit/presenter.py +146 -0
  76. cli/commands/content/get/__init__.py +1 -0
  77. cli/commands/content/get/command.py +39 -0
  78. cli/commands/content/get/presenter.py +176 -0
  79. cli/commands/content/list/__init__.py +1 -0
  80. cli/commands/content/list/command.py +347 -0
  81. cli/commands/content/list/export_formatters.py +409 -0
  82. cli/commands/content/list/export_handler.py +165 -0
  83. cli/commands/content/list/presenter.py +190 -0
  84. cli/commands/credentials/__init__.py +0 -0
  85. cli/commands/credentials/create/__init__.py +0 -0
  86. cli/commands/credentials/create/command.py +165 -0
  87. cli/commands/credentials/create/fields.py +38 -0
  88. cli/commands/credentials/create/presenter.py +20 -0
  89. cli/commands/credentials/update/__init__.py +0 -0
  90. cli/commands/credentials/update/command.py +53 -0
  91. cli/commands/credentials/update/fields.py +71 -0
  92. cli/commands/credentials/update/presenter.py +16 -0
  93. cli/commands/flag_utils.py +366 -0
  94. cli/commands/generate/__init__.py +0 -0
  95. cli/commands/generate/cancel/__init__.py +1 -0
  96. cli/commands/generate/cancel/command.py +44 -0
  97. cli/commands/generate/cancel/presenter.py +26 -0
  98. cli/commands/generate/status/__init__.py +1 -0
  99. cli/commands/generate/status/command.py +58 -0
  100. cli/commands/generate/status/presenter.py +78 -0
  101. cli/commands/generate/text/__init__.py +0 -0
  102. cli/commands/generate/text/command.py +1325 -0
  103. cli/commands/generate/text/concurrent_renderer.py +355 -0
  104. cli/commands/generate/text/presenter.py +287 -0
  105. cli/commands/generate/text/stream_renderer.py +129 -0
  106. cli/commands/knowledge/__init__.py +0 -0
  107. cli/commands/knowledge/collections/__init__.py +0 -0
  108. cli/commands/knowledge/collections/cluster/__init__.py +0 -0
  109. cli/commands/knowledge/collections/cluster/command.py +64 -0
  110. cli/commands/knowledge/collections/cluster/presenter.py +74 -0
  111. cli/commands/knowledge/collections/cluster_status/__init__.py +0 -0
  112. cli/commands/knowledge/collections/cluster_status/command.py +46 -0
  113. cli/commands/knowledge/collections/cluster_status/presenter.py +10 -0
  114. cli/commands/knowledge/collections/create/__init__.py +0 -0
  115. cli/commands/knowledge/collections/create/command.py +137 -0
  116. cli/commands/knowledge/collections/create/presenter.py +38 -0
  117. cli/commands/knowledge/collections/delete/__init__.py +1 -0
  118. cli/commands/knowledge/collections/delete/command.py +47 -0
  119. cli/commands/knowledge/collections/delete/presenter.py +20 -0
  120. cli/commands/knowledge/collections/get/__init__.py +1 -0
  121. cli/commands/knowledge/collections/get/command.py +30 -0
  122. cli/commands/knowledge/collections/get/presenter.py +44 -0
  123. cli/commands/knowledge/collections/list/__init__.py +1 -0
  124. cli/commands/knowledge/collections/list/command.py +41 -0
  125. cli/commands/knowledge/collections/list/presenter.py +68 -0
  126. cli/commands/knowledge/collections/update/__init__.py +0 -0
  127. cli/commands/knowledge/collections/update/command.py +97 -0
  128. cli/commands/knowledge/collections/update/presenter.py +42 -0
  129. cli/commands/knowledge/documents/__init__.py +0 -0
  130. cli/commands/knowledge/documents/bulk_metadata/__init__.py +0 -0
  131. cli/commands/knowledge/documents/bulk_metadata/command.py +119 -0
  132. cli/commands/knowledge/documents/bulk_metadata/presenter.py +36 -0
  133. cli/commands/knowledge/documents/delete/__init__.py +0 -0
  134. cli/commands/knowledge/documents/delete/command.py +47 -0
  135. cli/commands/knowledge/documents/delete/presenter.py +20 -0
  136. cli/commands/knowledge/documents/get/__init__.py +0 -0
  137. cli/commands/knowledge/documents/get/command.py +39 -0
  138. cli/commands/knowledge/documents/get/presenter.py +78 -0
  139. cli/commands/knowledge/documents/ingest/__init__.py +0 -0
  140. cli/commands/knowledge/documents/ingest/command.py +222 -0
  141. cli/commands/knowledge/documents/ingest/presenter.py +41 -0
  142. cli/commands/knowledge/documents/list/__init__.py +0 -0
  143. cli/commands/knowledge/documents/list/command.py +69 -0
  144. cli/commands/knowledge/documents/list/presenter.py +86 -0
  145. cli/commands/knowledge/documents/reingest/__init__.py +0 -0
  146. cli/commands/knowledge/documents/reingest/command.py +102 -0
  147. cli/commands/knowledge/documents/reingest/presenter.py +70 -0
  148. cli/commands/knowledge/documents/update/__init__.py +0 -0
  149. cli/commands/knowledge/documents/update/command.py +85 -0
  150. cli/commands/knowledge/documents/update/presenter.py +37 -0
  151. cli/commands/knowledge/recover/__init__.py +0 -0
  152. cli/commands/knowledge/recover/command.py +46 -0
  153. cli/commands/knowledge/recover/presenter.py +79 -0
  154. cli/commands/knowledge/search/__init__.py +0 -0
  155. cli/commands/knowledge/search/command.py +218 -0
  156. cli/commands/knowledge/search/presenter.py +111 -0
  157. cli/commands/knowledge/synthesis/__init__.py +0 -0
  158. cli/commands/knowledge/synthesis/create/__init__.py +0 -0
  159. cli/commands/knowledge/synthesis/create/command.py +127 -0
  160. cli/commands/knowledge/synthesis/create/presenter.py +33 -0
  161. cli/commands/knowledge/synthesis/delete/__init__.py +0 -0
  162. cli/commands/knowledge/synthesis/delete/command.py +53 -0
  163. cli/commands/knowledge/synthesis/delete/presenter.py +31 -0
  164. cli/commands/knowledge/synthesis/get/__init__.py +0 -0
  165. cli/commands/knowledge/synthesis/get/command.py +55 -0
  166. cli/commands/knowledge/synthesis/get/presenter.py +114 -0
  167. cli/commands/knowledge/synthesis/list/__init__.py +0 -0
  168. cli/commands/knowledge/synthesis/list/command.py +132 -0
  169. cli/commands/knowledge/synthesis/list/presenter.py +84 -0
  170. cli/commands/knowledge/synthesis/refresh/__init__.py +0 -0
  171. cli/commands/knowledge/synthesis/refresh/command.py +42 -0
  172. cli/commands/knowledge/synthesis/refresh/presenter.py +33 -0
  173. cli/commands/knowledge/synthesis/update/__init__.py +0 -0
  174. cli/commands/knowledge/synthesis/update/command.py +76 -0
  175. cli/commands/knowledge/synthesis/update/presenter.py +41 -0
  176. cli/commands/models/__init__.py +0 -0
  177. cli/commands/models/list/__init__.py +0 -0
  178. cli/commands/models/list/command.py +84 -0
  179. cli/commands/models/list/presenter.py +114 -0
  180. cli/commands/organizations/__init__.py +0 -0
  181. cli/commands/organizations/create/command.py +32 -0
  182. cli/commands/organizations/create/presenter.py +9 -0
  183. cli/commands/pipelines/__init__.py +1 -0
  184. cli/commands/pipelines/approvals/__init__.py +1 -0
  185. cli/commands/pipelines/approvals/decide_command.py +77 -0
  186. cli/commands/pipelines/approvals/get_command.py +44 -0
  187. cli/commands/pipelines/approvals/presenter.py +56 -0
  188. cli/commands/pipelines/costs/__init__.py +1 -0
  189. cli/commands/pipelines/costs/command.py +57 -0
  190. cli/commands/pipelines/costs/daily_command.py +54 -0
  191. cli/commands/pipelines/costs/daily_presenter.py +59 -0
  192. cli/commands/pipelines/costs/presenter.py +37 -0
  193. cli/commands/pipelines/create/__init__.py +1 -0
  194. cli/commands/pipelines/create/command.py +103 -0
  195. cli/commands/pipelines/create/presenter.py +22 -0
  196. cli/commands/pipelines/env_vars/__init__.py +1 -0
  197. cli/commands/pipelines/env_vars/command.py +51 -0
  198. cli/commands/pipelines/env_vars/presenter.py +16 -0
  199. cli/commands/pipelines/execute/__init__.py +1 -0
  200. cli/commands/pipelines/execute/command.py +142 -0
  201. cli/commands/pipelines/execute/presenter.py +47 -0
  202. cli/commands/pipelines/executions/__init__.py +1 -0
  203. cli/commands/pipelines/executions/costs/__init__.py +1 -0
  204. cli/commands/pipelines/executions/costs/command.py +48 -0
  205. cli/commands/pipelines/executions/costs/presenter.py +29 -0
  206. cli/commands/pipelines/executions/costs_by_model/__init__.py +1 -0
  207. cli/commands/pipelines/executions/costs_by_model/command.py +50 -0
  208. cli/commands/pipelines/executions/costs_by_model/presenter.py +78 -0
  209. cli/commands/pipelines/executions/costs_by_step/__init__.py +1 -0
  210. cli/commands/pipelines/executions/costs_by_step/command.py +50 -0
  211. cli/commands/pipelines/executions/costs_by_step/presenter.py +72 -0
  212. cli/commands/pipelines/executions/get_command.py +38 -0
  213. cli/commands/pipelines/executions/list_command.py +123 -0
  214. cli/commands/pipelines/executions/presenter.py +131 -0
  215. cli/commands/pipelines/executions/rerun_command.py +41 -0
  216. cli/commands/pipelines/executions/update/__init__.py +1 -0
  217. cli/commands/pipelines/executions/update/command.py +110 -0
  218. cli/commands/pipelines/executions/update/presenter.py +28 -0
  219. cli/commands/pipelines/get/__init__.py +1 -0
  220. cli/commands/pipelines/get/command.py +33 -0
  221. cli/commands/pipelines/get/presenter.py +48 -0
  222. cli/commands/pipelines/list/__init__.py +1 -0
  223. cli/commands/pipelines/list/command.py +53 -0
  224. cli/commands/pipelines/list/presenter.py +66 -0
  225. cli/commands/pipelines/schedules/__init__.py +1 -0
  226. cli/commands/pipelines/schedules/create_command.py +119 -0
  227. cli/commands/pipelines/schedules/create_presenter.py +35 -0
  228. cli/commands/pipelines/schedules/delete_command.py +52 -0
  229. cli/commands/pipelines/schedules/env_vars_command.py +59 -0
  230. cli/commands/pipelines/schedules/env_vars_presenter.py +16 -0
  231. cli/commands/pipelines/schedules/get_command.py +38 -0
  232. cli/commands/pipelines/schedules/list_command.py +33 -0
  233. cli/commands/pipelines/schedules/once_command.py +90 -0
  234. cli/commands/pipelines/schedules/once_presenter.py +30 -0
  235. cli/commands/pipelines/schedules/presenter.py +104 -0
  236. cli/commands/pipelines/schedules/update_command.py +139 -0
  237. cli/commands/pipelines/schedules/update_presenter.py +29 -0
  238. cli/commands/render/__init__.py +0 -0
  239. cli/commands/render/html_to_image/__init__.py +0 -0
  240. cli/commands/render/html_to_image/command.py +170 -0
  241. cli/commands/schemas/__init__.py +0 -0
  242. cli/commands/schemas/create/__init__.py +0 -0
  243. cli/commands/schemas/create/command.py +122 -0
  244. cli/commands/schemas/create/presenter.py +53 -0
  245. cli/commands/schemas/delete/command.py +45 -0
  246. cli/commands/schemas/delete/presenter.py +9 -0
  247. cli/commands/schemas/get/__init__.py +0 -0
  248. cli/commands/schemas/get/command.py +56 -0
  249. cli/commands/schemas/get/presenter.py +129 -0
  250. cli/commands/schemas/list/__init__.py +0 -0
  251. cli/commands/schemas/list/command.py +64 -0
  252. cli/commands/schemas/list/presenter.py +133 -0
  253. cli/commands/schemas/update/__init__.py +0 -0
  254. cli/commands/schemas/update/command.py +369 -0
  255. cli/commands/schemas/update/presenter.py +53 -0
  256. cli/commands/sessions/__init__.py +1 -0
  257. cli/commands/sessions/delete/__init__.py +1 -0
  258. cli/commands/sessions/delete/command.py +47 -0
  259. cli/commands/sessions/delete/presenter.py +10 -0
  260. cli/commands/sessions/get/__init__.py +1 -0
  261. cli/commands/sessions/get/command.py +42 -0
  262. cli/commands/sessions/get/presenter.py +59 -0
  263. cli/commands/sessions/list/__init__.py +1 -0
  264. cli/commands/sessions/list/command.py +61 -0
  265. cli/commands/sessions/list/presenter.py +68 -0
  266. cli/commands/sessions/messages/__init__.py +1 -0
  267. cli/commands/sessions/messages/command.py +78 -0
  268. cli/commands/sessions/messages/presenter.py +79 -0
  269. cli/commands/shared_flags.py +500 -0
  270. cli/commands/sync/__init__.py +0 -0
  271. cli/commands/sync/command.py +45 -0
  272. cli/commands/sync/presenter.py +49 -0
  273. cli/commands/tags/__init__.py +1 -0
  274. cli/commands/tags/create/__init__.py +1 -0
  275. cli/commands/tags/create/command.py +60 -0
  276. cli/commands/tags/delete/__init__.py +1 -0
  277. cli/commands/tags/delete/command.py +47 -0
  278. cli/commands/tags/delete/presenter.py +10 -0
  279. cli/commands/tags/get/command.py +31 -0
  280. cli/commands/tags/get/presenter.py +23 -0
  281. cli/commands/tags/list/__init__.py +1 -0
  282. cli/commands/tags/list/command.py +52 -0
  283. cli/commands/tags/list/presenter.py +49 -0
  284. cli/commands/tags/update/command.py +64 -0
  285. cli/commands/tags/update/presenter.py +9 -0
  286. cli/commands/templates/__init__.py +0 -0
  287. cli/commands/templates/create/__init__.py +0 -0
  288. cli/commands/templates/create/command.py +152 -0
  289. cli/commands/templates/create/presenter.py +86 -0
  290. cli/commands/templates/delete/__init__.py +0 -0
  291. cli/commands/templates/delete/command.py +47 -0
  292. cli/commands/templates/delete/presenter.py +16 -0
  293. cli/commands/templates/get/__init__.py +0 -0
  294. cli/commands/templates/get/command.py +52 -0
  295. cli/commands/templates/get/presenter.py +233 -0
  296. cli/commands/templates/get_by_version/command.py +32 -0
  297. cli/commands/templates/get_by_version/presenter.py +30 -0
  298. cli/commands/templates/list/__init__.py +1 -0
  299. cli/commands/templates/list/command.py +102 -0
  300. cli/commands/templates/list/presenter.py +93 -0
  301. cli/commands/templates/render/__init__.py +0 -0
  302. cli/commands/templates/render/command.py +115 -0
  303. cli/commands/templates/render/presenter.py +276 -0
  304. cli/commands/templates/update/__init__.py +0 -0
  305. cli/commands/templates/update/command.py +199 -0
  306. cli/commands/templates/update/presenter.py +94 -0
  307. cli/commands/templates/version/__init__.py +1 -0
  308. cli/commands/templates/version/command.py +116 -0
  309. cli/commands/templates/version/presenter.py +100 -0
  310. cli/commands/tool_configs/__init__.py +0 -0
  311. cli/commands/tool_configs/create/__init__.py +0 -0
  312. cli/commands/tool_configs/create/command.py +118 -0
  313. cli/commands/tool_configs/create/presenter.py +53 -0
  314. cli/commands/tool_configs/delete/__init__.py +0 -0
  315. cli/commands/tool_configs/delete/command.py +47 -0
  316. cli/commands/tool_configs/delete/presenter.py +18 -0
  317. cli/commands/tool_configs/get/__init__.py +0 -0
  318. cli/commands/tool_configs/get/command.py +31 -0
  319. cli/commands/tool_configs/get/presenter.py +62 -0
  320. cli/commands/tool_configs/list/__init__.py +0 -0
  321. cli/commands/tool_configs/list/command.py +59 -0
  322. cli/commands/tool_configs/list/presenter.py +60 -0
  323. cli/commands/tool_configs/update/__init__.py +0 -0
  324. cli/commands/tool_configs/update/command.py +128 -0
  325. cli/commands/tool_configs/update/presenter.py +53 -0
  326. cli/commands/tools/__init__.py +1 -0
  327. cli/commands/tools/get/__init__.py +1 -0
  328. cli/commands/tools/get/command.py +42 -0
  329. cli/commands/tools/get/presenter.py +45 -0
  330. cli/commands/tools/list/__init__.py +1 -0
  331. cli/commands/tools/list/command.py +56 -0
  332. cli/commands/tools/list/presenter.py +44 -0
  333. cli/commands/users/__init__.py +0 -0
  334. cli/commands/users/create/command.py +53 -0
  335. cli/commands/users/create/presenter.py +9 -0
  336. cli/commands/whoami/__init__.py +0 -0
  337. cli/commands/whoami/command.py +42 -0
  338. cli/infrastructure/__init__.py +0 -0
  339. cli/infrastructure/auth_storage.py +71 -0
  340. cli/infrastructure/client_factory.py +36 -0
  341. cli/infrastructure/command.py +75 -0
  342. cli/infrastructure/config.py +188 -0
  343. cli/infrastructure/console.py +27 -0
  344. cli/infrastructure/editor.py +138 -0
  345. cli/infrastructure/error_display.py +178 -0
  346. cli/infrastructure/field_extractor.py +360 -0
  347. cli/infrastructure/file_content.py +210 -0
  348. cli/infrastructure/filter_parser.py +256 -0
  349. cli/infrastructure/formatters/__init__.py +0 -0
  350. cli/infrastructure/formatters/base.py +99 -0
  351. cli/infrastructure/formatters/compact_formatter.py +245 -0
  352. cli/infrastructure/formatters/json_formatter.py +84 -0
  353. cli/infrastructure/formatters/lines_formatter.py +102 -0
  354. cli/infrastructure/formatting/__init__.py +0 -0
  355. cli/infrastructure/formatting/fields.py +193 -0
  356. cli/infrastructure/forms/__init__.py +0 -0
  357. cli/infrastructure/forms/agent_picker.py +123 -0
  358. cli/infrastructure/forms/agent_tool_editor.py +384 -0
  359. cli/infrastructure/forms/agent_tools_manager.py +212 -0
  360. cli/infrastructure/forms/base_picker.py +469 -0
  361. cli/infrastructure/forms/components.py +126 -0
  362. cli/infrastructure/forms/json_schema_builder.py +149 -0
  363. cli/infrastructure/forms/model_picker.py +134 -0
  364. cli/infrastructure/forms/parsers.py +173 -0
  365. cli/infrastructure/forms/resolution_modal.py +302 -0
  366. cli/infrastructure/forms/schema_picker.py +137 -0
  367. cli/infrastructure/forms/tag_management_modal.py +103 -0
  368. cli/infrastructure/forms/tag_picker.py +207 -0
  369. cli/infrastructure/forms/template_picker.py +131 -0
  370. cli/infrastructure/forms/tool_config_picker.py +130 -0
  371. cli/infrastructure/forms/tool_picker.py +103 -0
  372. cli/infrastructure/injection/__init__.py +0 -0
  373. cli/infrastructure/injection/parser.py +302 -0
  374. cli/infrastructure/injection/resolver.py +399 -0
  375. cli/infrastructure/kv_parser.py +130 -0
  376. cli/infrastructure/local_storage.py +227 -0
  377. cli/infrastructure/macro_parser.py +215 -0
  378. cli/infrastructure/output.py +192 -0
  379. cli/infrastructure/provider_setup.py +81 -0
  380. cli/infrastructure/renderers/__init__.py +0 -0
  381. cli/infrastructure/renderers/entity_renderer.py +77 -0
  382. cli/infrastructure/renderers/list_renderer.py +114 -0
  383. cli/infrastructure/scope_utils.py +47 -0
  384. cli/infrastructure/spinner.py +101 -0
  385. cli/infrastructure/tui/__init__.py +0 -0
  386. cli/infrastructure/tui/clipboard.py +41 -0
  387. cli/infrastructure/tui/formatters.py +105 -0
  388. cli/infrastructure/tui/preview.py +14 -0
  389. cli/infrastructure/tui/selectable.py +198 -0
  390. cli/infrastructure/validation/__init__.py +0 -0
  391. cli/infrastructure/validation/tag_validation.py +74 -0
  392. cli/main.py +759 -0
  393. cli/tui/__init__.py +0 -0
  394. cli/tui/app.py +199 -0
  395. cli/tui/app_store.py +73 -0
  396. cli/tui/chat/__init__.py +0 -0
  397. cli/tui/chat/commands/__init__.py +0 -0
  398. cli/tui/chat/commands/base.py +65 -0
  399. cli/tui/chat/commands/create_session.py +135 -0
  400. cli/tui/chat/commands/load_session.py +119 -0
  401. cli/tui/chat/commands/regenerate.py +120 -0
  402. cli/tui/chat/commands/reload_session.py +63 -0
  403. cli/tui/chat/commands/send_message.py +190 -0
  404. cli/tui/chat/commands/undo.py +66 -0
  405. cli/tui/chat/editor.py +71 -0
  406. cli/tui/chat/messages.py +223 -0
  407. cli/tui/chat/pane.py +141 -0
  408. cli/tui/chat/renderers/__init__.py +0 -0
  409. cli/tui/chat/renderers/base.py +72 -0
  410. cli/tui/chat/renderers/markdown.py +250 -0
  411. cli/tui/chat/renderers/plain.py +83 -0
  412. cli/tui/chat/screen.py +1155 -0
  413. cli/tui/chat/services/__init__.py +0 -0
  414. cli/tui/chat/services/injection.py +386 -0
  415. cli/tui/chat/services/name_generator.py +256 -0
  416. cli/tui/chat/slash_commands.py +424 -0
  417. cli/tui/chat/store.py +280 -0
  418. cli/tui/chat/types.py +220 -0
  419. cli/tui/chat/widgets/__init__.py +0 -0
  420. cli/tui/chat/widgets/chat_header.py +75 -0
  421. cli/tui/chat/widgets/chat_input.py +362 -0
  422. cli/tui/chat/widgets/injection_popup.py +161 -0
  423. cli/tui/chat/widgets/message_display.py +287 -0
  424. cli/tui/chat/widgets/session_sidebar.py +214 -0
  425. cli/tui/chat/widgets/welcome_screen.py +290 -0
  426. cli/tui/screens/__init__.py +0 -0
  427. cli/tui/screens/agents.py +344 -0
  428. cli/tui/screens/base.py +301 -0
  429. cli/tui/screens/content.py +508 -0
  430. cli/tui/screens/dashboard.py +89 -0
  431. cli/tui/screens/models.py +96 -0
  432. cli/tui/screens/nav_screen.py +186 -0
  433. cli/tui/screens/schemas.py +522 -0
  434. cli/tui/screens/templates.py +734 -0
  435. cli/tui/screens/tool_configs.py +335 -0
  436. cli/tui/styles/__init__.py +0 -0
  437. cli/tui/widgets/__init__.py +0 -0
  438. cli/tui/widgets/agent_create_modal.py +139 -0
  439. cli/tui/widgets/agent_form_modal.py +659 -0
  440. cli/tui/widgets/agent_update_modal.py +299 -0
  441. cli/tui/widgets/base_form_modal.py +77 -0
  442. cli/tui/widgets/confirm_modal.py +75 -0
  443. cli/tui/widgets/help_modal.py +145 -0
  444. cli/tui/widgets/new_session_modal.py +328 -0
  445. cli/tui/widgets/schema_create_modal.py +271 -0
  446. cli/tui/widgets/schema_update_modal.py +188 -0
  447. cli/tui/widgets/status_footer.py +147 -0
  448. cli/tui/widgets/template_create_modal.py +502 -0
  449. cli/tui/widgets/template_update_modal.py +308 -0
  450. cli/tui/widgets/tool_config_create_modal.py +216 -0
  451. cli/tui/widgets/tool_config_update_modal.py +208 -0
@@ -0,0 +1,129 @@
1
+ """Streaming text renderer with thinking block support.
2
+
3
+ Provides a terminal display for streaming text generation,
4
+ with visual differentiation between thinking/reasoning blocks
5
+ and generated content.
6
+
7
+ Streams both thinking and content in real-time:
8
+ - Thinking blocks are displayed in red with <thinking> tags to stderr
9
+ - Content is streamed directly to stdout
10
+ """
11
+
12
+ import sys
13
+ from collections.abc import AsyncGenerator
14
+
15
+ from rich.console import Console
16
+
17
+ from alloy_runtime_types.dtos.generation import GenerateTextStreamChunk
18
+
19
+ # ANSI escape codes
20
+ RED = "\033[31m"
21
+ RESET = "\033[0m"
22
+
23
+
24
+ class StreamRenderer:
25
+ """Renders streaming text generation with thinking block support.
26
+
27
+ Features:
28
+ - Thinking/reasoning blocks displayed in real-time (to stderr, in red)
29
+ - Content output to stdout in real-time
30
+ - Both thinking and content stream as they arrive
31
+ """
32
+
33
+ def __init__(self, console: Console):
34
+ """Initialize stream renderer.
35
+
36
+ Args:
37
+ console: Rich console for output
38
+ """
39
+ self.console = console
40
+ self._thinking_text = ""
41
+ self._content_text = ""
42
+ self._session_id: str | None = None
43
+ self._in_thinking_block = False
44
+
45
+ async def render_stream(
46
+ self,
47
+ stream: AsyncGenerator[GenerateTextStreamChunk, None],
48
+ show_thinking: bool = True,
49
+ ) -> tuple[str, str, str | None]:
50
+ """Render a streaming generation.
51
+
52
+ Streams both thinking and content in real-time as chunks arrive.
53
+
54
+ Args:
55
+ stream: Async generator of stream chunks
56
+ show_thinking: Whether to display thinking blocks (default True)
57
+
58
+ Returns:
59
+ Tuple of (content_text, thinking_text, session_id) - accumulated outputs
60
+ """
61
+ self._thinking_text = ""
62
+ self._content_text = ""
63
+ self._session_id = None
64
+ self._in_thinking_block = False
65
+
66
+ async for chunk in stream:
67
+ self._process_chunk(chunk, show_thinking)
68
+
69
+ # Close thinking block if still open at end of stream
70
+ if self._in_thinking_block:
71
+ self._close_thinking_block()
72
+
73
+ # Final newline for clean output
74
+ if self._content_text:
75
+ sys.stdout.write("\n")
76
+ sys.stdout.flush()
77
+
78
+ return self._content_text, self._thinking_text, self._session_id
79
+
80
+ def _process_chunk(
81
+ self, chunk: GenerateTextStreamChunk, show_thinking: bool
82
+ ) -> None:
83
+ """Process a stream chunk.
84
+
85
+ Args:
86
+ chunk: Stream chunk to process
87
+ show_thinking: Whether to display thinking text
88
+ """
89
+ if chunk.chunk_type == "thinking":
90
+ # Thinking chunks - stream in real-time
91
+ if chunk.reasoning_content:
92
+ self._thinking_text += chunk.reasoning_content
93
+ if show_thinking:
94
+ # Open thinking block if not already open
95
+ if not self._in_thinking_block:
96
+ self._open_thinking_block()
97
+ # Stream thinking content immediately
98
+ sys.stderr.write(f"{RED}{chunk.reasoning_content}{RESET}")
99
+ sys.stderr.flush()
100
+
101
+ elif chunk.chunk_type == "metadata":
102
+ # Metadata chunks - capture session_id from final metadata
103
+ if chunk.metadata and "chat_session_id" in chunk.metadata:
104
+ self._session_id = chunk.metadata["chat_session_id"]
105
+
106
+ else:
107
+ # Content chunks - close thinking block first if open
108
+ if self._in_thinking_block:
109
+ self._close_thinking_block()
110
+
111
+ if chunk.content:
112
+ self._content_text += chunk.content
113
+ # Stream content immediately
114
+ sys.stdout.write(chunk.content)
115
+ sys.stdout.flush()
116
+
117
+ def _open_thinking_block(self) -> None:
118
+ """Print opening thinking tag to stderr."""
119
+ sys.stderr.write(f"\n{RED}<thinking>{RESET}\n")
120
+ sys.stderr.flush()
121
+ self._in_thinking_block = True
122
+
123
+ def _close_thinking_block(self) -> None:
124
+ """Print closing thinking tag to stderr."""
125
+ if not self._thinking_text.endswith("\n"):
126
+ sys.stderr.write("\n")
127
+ sys.stderr.write(f"{RED}</thinking>{RESET}\n\n")
128
+ sys.stderr.flush()
129
+ self._in_thinking_block = False
File without changes
File without changes
File without changes
@@ -0,0 +1,64 @@
1
+ """Knowledge collection cluster command implementation."""
2
+
3
+ import typer
4
+
5
+ from cli.commands.knowledge.collections.cluster.presenter import (
6
+ present_cluster_status,
7
+ present_cluster_triggered,
8
+ )
9
+ from cli.infrastructure.command import async_command, authenticated_client
10
+
11
+
12
+ def knowledge_collections_cluster_command(
13
+ collection: str = typer.Argument(
14
+ ...,
15
+ help="Collection name or UUID",
16
+ ),
17
+ wait: bool = typer.Option(
18
+ False,
19
+ "--wait",
20
+ help="Wait for clustering to complete before returning",
21
+ ),
22
+ timeout: float = typer.Option(
23
+ 300.0,
24
+ "--timeout",
25
+ help="Maximum seconds to wait when using --wait (default: 300)",
26
+ ),
27
+ ) -> None:
28
+ """Trigger clustering for a knowledge collection.
29
+
30
+ Queues an asynchronous clustering run. Use --wait to block until complete.
31
+
32
+ Examples:
33
+ ai2 knowledge collections cluster my-collection
34
+ ai2 kb collections cluster 550e8400-e29b-41d4-a716-446655440000 --wait
35
+ ai2 kb collections cluster my-collection --wait --timeout 600
36
+ """
37
+ _execute_cluster(
38
+ collection_identifier=collection,
39
+ wait=wait,
40
+ timeout=timeout,
41
+ )
42
+
43
+
44
+ @async_command
45
+ async def _execute_cluster(
46
+ collection_identifier: str,
47
+ wait: bool,
48
+ timeout: float,
49
+ ) -> None:
50
+ """Execute cluster operation."""
51
+ async with authenticated_client() as (_config, client):
52
+ response = await client.trigger_collection_clustering(collection_identifier)
53
+
54
+ present_cluster_triggered(response)
55
+
56
+ if wait:
57
+ async with authenticated_client() as (_config, client):
58
+ status = await client.wait_for_collection_clustering(
59
+ collection_identifier,
60
+ task_id=response.task_id,
61
+ timeout=timeout,
62
+ )
63
+
64
+ present_cluster_status(status)
@@ -0,0 +1,74 @@
1
+ """Presenter for knowledge collection cluster command output."""
2
+
3
+ from rich.panel import Panel
4
+ from rich.table import Table
5
+
6
+ from cli.infrastructure.formatting.fields import (
7
+ format_datetime,
8
+ format_optional,
9
+ format_uuid,
10
+ )
11
+ from cli.infrastructure.output import OutputService
12
+ from alloy_runtime_types.dtos.knowledge import (
13
+ GetCollectionClusteringStatusResponse,
14
+ TriggerCollectionClusteringResponse,
15
+ )
16
+
17
+
18
+ def present_cluster_triggered(response: TriggerCollectionClusteringResponse) -> None:
19
+ """Present clustering trigger result.
20
+
21
+ Args:
22
+ response: TriggerCollectionClusteringResponse from server
23
+ """
24
+ output = OutputService.get()
25
+
26
+ output.success(response.message)
27
+
28
+ table = Table(show_header=False, box=None, padding=(0, 1))
29
+ table.add_column("Field", style="dim")
30
+ table.add_column("Value")
31
+
32
+ table.add_row("Collection ID", format_uuid(response.collection_id, short=False))
33
+ table.add_row("Task ID", response.task_id)
34
+ table.add_row("Status", response.status)
35
+
36
+ panel = Panel(table, title="Clustering Triggered", border_style="green")
37
+ output.console.print(panel)
38
+
39
+
40
+ def present_cluster_status(
41
+ response: GetCollectionClusteringStatusResponse,
42
+ ) -> None:
43
+ """Present clustering status details.
44
+
45
+ Args:
46
+ response: GetCollectionClusteringStatusResponse from server
47
+ """
48
+ output = OutputService.get()
49
+
50
+ # Choose border style based on status
51
+ border_style = {
52
+ "completed": "green",
53
+ "failed": "red",
54
+ "processing": "yellow",
55
+ "pending": "dim",
56
+ }.get(response.status, "dim")
57
+
58
+ table = Table(show_header=False, box=None, padding=(0, 1))
59
+ table.add_column("Field", style="dim")
60
+ table.add_column("Value")
61
+
62
+ table.add_row("Collection ID", format_uuid(response.collection_id, short=False))
63
+ table.add_row("Status", response.status)
64
+ table.add_row("Cluster Count", str(response.cluster_count))
65
+ table.add_row("Total Chunks", str(response.total_chunks))
66
+ table.add_row("Clustered Chunks", str(response.clustered_chunks))
67
+ table.add_row("Noise Chunks", str(response.noise_chunks))
68
+ table.add_row("Unclustered Chunks", str(response.unclustered_chunks))
69
+ table.add_row("Message", format_optional(response.message))
70
+ table.add_row("Error", format_optional(response.error_message))
71
+ table.add_row("Last Cluster Run", format_datetime(response.last_cluster_run_at))
72
+
73
+ panel = Panel(table, title="Clustering Status", border_style=border_style)
74
+ output.console.print(panel)
@@ -0,0 +1,46 @@
1
+ """Knowledge collection cluster-status command implementation."""
2
+
3
+ import typer
4
+
5
+ from cli.commands.knowledge.collections.cluster.presenter import present_cluster_status
6
+ from cli.infrastructure.command import async_command, authenticated_client
7
+
8
+
9
+ def knowledge_collections_cluster_status_command(
10
+ collection: str = typer.Argument(
11
+ ...,
12
+ help="Collection name or UUID",
13
+ ),
14
+ task_id: str = typer.Option(
15
+ ...,
16
+ "--task-id",
17
+ help="Celery task ID returned by the cluster trigger command",
18
+ ),
19
+ ) -> None:
20
+ """Get clustering status for a knowledge collection.
21
+
22
+ Requires a task ID from a previous cluster trigger.
23
+
24
+ Examples:
25
+ ai2 knowledge collections cluster-status my-collection --task-id abc-123
26
+ ai2 kb collections cluster-status 550e8400-... --task-id abc-123
27
+ """
28
+ _execute_cluster_status(
29
+ collection_identifier=collection,
30
+ task_id=task_id,
31
+ )
32
+
33
+
34
+ @async_command
35
+ async def _execute_cluster_status(
36
+ collection_identifier: str,
37
+ task_id: str,
38
+ ) -> None:
39
+ """Execute cluster status operation."""
40
+ async with authenticated_client() as (_config, client):
41
+ response = await client.get_collection_clustering_status(
42
+ collection_identifier,
43
+ task_id=task_id,
44
+ )
45
+
46
+ present_cluster_status(response)
@@ -0,0 +1,10 @@
1
+ """Presenter for knowledge collection cluster-status command output.
2
+
3
+ This module re-exports the shared presenter from the cluster command.
4
+ The cluster-status command and the cluster --wait command both display
5
+ the same status format.
6
+ """
7
+
8
+ from cli.commands.knowledge.collections.cluster.presenter import present_cluster_status
9
+
10
+ __all__ = ["present_cluster_status"]
File without changes
@@ -0,0 +1,137 @@
1
+ """Knowledge collection create command implementation."""
2
+
3
+ from typing import Optional
4
+
5
+ import typer
6
+
7
+ from cli.commands.flag_utils import validate_section_strategy
8
+ from cli.commands.knowledge.collections.create.presenter import (
9
+ present_collection_create_success,
10
+ )
11
+ from cli.infrastructure.command import async_command, authenticated_client
12
+ from alloy_runtime_types.dtos.knowledge import CreateCollectionRequest
13
+
14
+
15
+ def knowledge_collections_create_command(
16
+ name: str = typer.Option(
17
+ ...,
18
+ "-n",
19
+ "--name",
20
+ help="Collection name",
21
+ ),
22
+ description: Optional[str] = typer.Option(
23
+ None,
24
+ "-d",
25
+ "--description",
26
+ help="Collection description",
27
+ ),
28
+ chunk_size: int = typer.Option(
29
+ 512,
30
+ "-c",
31
+ "--chunk-size",
32
+ min=64,
33
+ max=8192,
34
+ help="Target tokens per chunk (64-8192)",
35
+ ),
36
+ chunk_overlap: int = typer.Option(
37
+ 50,
38
+ "-o",
39
+ "--chunk-overlap",
40
+ min=0,
41
+ help="Token overlap between chunks",
42
+ ),
43
+ section_strategy: str = typer.Option(
44
+ "paragraph_based",
45
+ "-s",
46
+ "--section-strategy",
47
+ help="Section extraction strategy: heading_based, paragraph_based, fixed_size, none",
48
+ ),
49
+ dedup_threshold: Optional[float] = typer.Option(
50
+ None,
51
+ "--dedup-threshold",
52
+ min=0.50,
53
+ max=1.00,
54
+ help="Dedup similarity threshold (0.50-1.00). Default: 0.95",
55
+ ),
56
+ disable_dedup: bool = typer.Option(
57
+ False,
58
+ "--disable-dedup",
59
+ help="Disable chunk deduplication entirely",
60
+ ),
61
+ rerank_instruction: Optional[str] = typer.Option(
62
+ None,
63
+ "-r",
64
+ "--rerank-instruction",
65
+ help="Default instruction for Voyage AI reranking (max 500 chars)",
66
+ ),
67
+ ) -> None:
68
+ """Create a new knowledge collection.
69
+
70
+ Examples:
71
+ ai2 knowledge collections create -n "Product Docs"
72
+ ai2 knowledge collections create -n "Support" -d "Support articles" -c 1024
73
+ ai2 kb collections create -n "Wiki" -s heading_based
74
+ ai2 kb collections create -n "NoDedup" --disable-dedup
75
+ ai2 kb collections create -n "StrictDedup" --dedup-threshold 0.99
76
+ """
77
+ _execute_create_from_flags(
78
+ name=name,
79
+ description=description,
80
+ chunk_size=chunk_size,
81
+ chunk_overlap=chunk_overlap,
82
+ section_strategy=section_strategy,
83
+ dedup_threshold=dedup_threshold,
84
+ disable_dedup=disable_dedup,
85
+ rerank_instruction=rerank_instruction,
86
+ )
87
+
88
+
89
+ @async_command
90
+ async def _execute_create(request: CreateCollectionRequest) -> None:
91
+ """Execute the collection creation with the given request."""
92
+ async with authenticated_client() as (_config, client):
93
+ response = await client.create_collection(request)
94
+
95
+ present_collection_create_success(response)
96
+
97
+
98
+ def _execute_create_from_flags(
99
+ name: str,
100
+ description: Optional[str],
101
+ chunk_size: int,
102
+ chunk_overlap: int,
103
+ section_strategy: str,
104
+ dedup_threshold: Optional[float],
105
+ disable_dedup: bool,
106
+ rerank_instruction: Optional[str],
107
+ ) -> None:
108
+ """Build and execute collection creation from command flags."""
109
+ strategy = validate_section_strategy(section_strategy)
110
+
111
+ if chunk_overlap >= chunk_size:
112
+ raise typer.BadParameter(
113
+ f"Chunk overlap ({chunk_overlap}) must be less than chunk size ({chunk_size})"
114
+ )
115
+
116
+ if disable_dedup and dedup_threshold is not None:
117
+ raise typer.BadParameter("Cannot use --disable-dedup with --dedup-threshold")
118
+
119
+ final_dedup_threshold: float | None
120
+ if disable_dedup:
121
+ final_dedup_threshold = None
122
+ elif dedup_threshold is not None:
123
+ final_dedup_threshold = dedup_threshold
124
+ else:
125
+ final_dedup_threshold = 0.95
126
+
127
+ request = CreateCollectionRequest(
128
+ name=name,
129
+ description=description,
130
+ chunk_size_tokens=chunk_size,
131
+ chunk_overlap_tokens=chunk_overlap,
132
+ section_strategy=strategy,
133
+ dedup_similarity_threshold=final_dedup_threshold,
134
+ rerank_instruction=rerank_instruction,
135
+ )
136
+
137
+ _execute_create(request)
@@ -0,0 +1,38 @@
1
+ """Presenter for collection creation output."""
2
+
3
+ from rich.panel import Panel
4
+ from rich.table import Table
5
+
6
+ from cli.infrastructure.formatting.fields import (
7
+ format_optional,
8
+ format_uuid,
9
+ )
10
+ from cli.infrastructure.output import OutputService
11
+ from alloy_runtime_types.dtos.knowledge import CreateCollectionResponse
12
+
13
+
14
+ def present_collection_create_success(response: CreateCollectionResponse) -> None:
15
+ """Present successful collection creation.
16
+
17
+ Args:
18
+ response: Collection creation response from server
19
+ """
20
+ output = OutputService.get()
21
+
22
+ output.success("Collection created successfully")
23
+
24
+ # Build a simple table for entity display
25
+ table = Table(show_header=False, box=None, padding=(0, 1))
26
+ table.add_column("Field", style="dim")
27
+ table.add_column("Value")
28
+
29
+ table.add_row("ID", format_uuid(response.id, short=False))
30
+ table.add_row("Name", response.name)
31
+ table.add_row("Description", format_optional(response.description))
32
+ table.add_row("Embedding Model", response.embedding_model)
33
+ table.add_row("Chunk Size", f"{response.chunk_size_tokens} tokens")
34
+ table.add_row("Chunk Overlap", f"{response.chunk_overlap_tokens} tokens")
35
+ table.add_row("Section Strategy", response.section_strategy)
36
+
37
+ panel = Panel(table, title=f"Collection: {response.name}", border_style="green")
38
+ output.console.print(panel)
@@ -0,0 +1,47 @@
1
+ """Knowledge collections delete command implementation."""
2
+
3
+ import typer
4
+
5
+ from cli.commands.knowledge.collections.delete.presenter import present_delete_result
6
+ from cli.infrastructure.command import async_command, authenticated_client
7
+ from cli.infrastructure.console import Confirm
8
+
9
+
10
+ def knowledge_collections_delete_command(
11
+ collection: str = typer.Argument(
12
+ ...,
13
+ help="Collection name or UUID",
14
+ ),
15
+ yes: bool = typer.Option(
16
+ False,
17
+ "-y",
18
+ "--yes",
19
+ help="Skip confirmation",
20
+ ),
21
+ ) -> None:
22
+ """Delete a collection and all its documents.
23
+
24
+ Permanently removes the collection and all associated documents and chunks.
25
+
26
+ Examples:
27
+ ai2 knowledge collections delete my-collection
28
+ ai2 kb collections delete 550e8400-e29b-41d4-a716-446655440000 -y
29
+ """
30
+ _execute_delete(collection_identifier=collection, skip_confirm=yes)
31
+
32
+
33
+ @async_command
34
+ async def _execute_delete(collection_identifier: str, skip_confirm: bool) -> None:
35
+ """Execute delete collection operation."""
36
+ if not skip_confirm:
37
+ confirmed = Confirm.ask(
38
+ f"[yellow]Delete collection '{collection_identifier}'?[/yellow] "
39
+ "This will delete all documents and cannot be undone"
40
+ )
41
+ if not confirmed:
42
+ raise typer.Abort()
43
+
44
+ async with authenticated_client() as (_config, client):
45
+ response = await client.delete_collection(collection_identifier)
46
+
47
+ present_delete_result(response)
@@ -0,0 +1,20 @@
1
+ """Presenter for knowledge collection delete command output."""
2
+
3
+ from cli.infrastructure.output import OutputService
4
+ from alloy_runtime_types.dtos.knowledge import DeleteCollectionResponse
5
+
6
+
7
+ def present_delete_result(response: DeleteCollectionResponse) -> None:
8
+ """Present collection deletion result.
9
+
10
+ Args:
11
+ response: DeleteCollectionResponse from server
12
+ """
13
+ output = OutputService.get()
14
+
15
+ docs_msg = (
16
+ f" ({response.documents_deleted} documents deleted)"
17
+ if response.documents_deleted > 0
18
+ else ""
19
+ )
20
+ output.success(f"Collection '{response.name}' deleted successfully{docs_msg}")
@@ -0,0 +1,30 @@
1
+ """Knowledge collections get command implementation."""
2
+
3
+ import typer
4
+
5
+ from cli.commands.knowledge.collections.get.presenter import present_collection_details
6
+ from cli.infrastructure.command import async_command, authenticated_client
7
+
8
+
9
+ def knowledge_collections_get_command(
10
+ collection: str = typer.Argument(
11
+ ...,
12
+ help="Collection name or UUID",
13
+ ),
14
+ ) -> None:
15
+ """Get collection details.
16
+
17
+ Examples:
18
+ ai2 knowledge collections get my-collection
19
+ ai2 kb collections get 550e8400-e29b-41d4-a716-446655440000
20
+ """
21
+ _execute_get(collection_identifier=collection)
22
+
23
+
24
+ @async_command
25
+ async def _execute_get(collection_identifier: str) -> None:
26
+ """Execute get collection operation."""
27
+ async with authenticated_client() as (_config, client):
28
+ response = await client.get_collection(collection_identifier)
29
+
30
+ present_collection_details(response)
@@ -0,0 +1,44 @@
1
+ """Presenter for knowledge collection get command output."""
2
+
3
+ from rich.panel import Panel
4
+ from rich.table import Table
5
+
6
+ from cli.infrastructure.formatting.fields import (
7
+ format_datetime,
8
+ format_optional,
9
+ format_uuid,
10
+ )
11
+ from cli.infrastructure.output import OutputService
12
+ from alloy_runtime_types.dtos.knowledge import GetCollectionResponse
13
+
14
+
15
+ def present_collection_details(response: GetCollectionResponse) -> None:
16
+ """Present collection details with Rich formatting.
17
+
18
+ Args:
19
+ response: GetCollectionResponse from server
20
+ """
21
+ output = OutputService.get()
22
+
23
+ table = Table(show_header=False, box=None, padding=(0, 1))
24
+ table.add_column("Field", style="dim")
25
+ table.add_column("Value")
26
+
27
+ table.add_row("ID", format_uuid(response.id, short=False))
28
+ table.add_row("Name", response.name)
29
+ table.add_row("Description", format_optional(response.description))
30
+ table.add_row("Embedding Model", response.embedding_model)
31
+ table.add_row("Embedding Dimensions", str(response.embedding_dimensions))
32
+ table.add_row("Chunk Size", f"{response.chunk_size_tokens} tokens")
33
+ table.add_row("Chunk Overlap", f"{response.chunk_overlap_tokens} tokens")
34
+ table.add_row("Section Strategy", response.section_strategy)
35
+ table.add_row("Document Count", str(response.document_count))
36
+ table.add_row("Created At", format_datetime(response.created_at))
37
+ table.add_row("Updated At", format_datetime(response.updated_at))
38
+
39
+ panel = Panel(
40
+ table,
41
+ title=f"Collection: {response.name}",
42
+ border_style="green",
43
+ )
44
+ output.console.print(panel)