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,500 @@
1
+ """Shared CLI flag definitions for consistent flag naming across commands.
2
+
3
+ This module provides reusable typer.Option instances that can be imported
4
+ and used directly in command function signatures. This ensures:
5
+ - Consistent short/long flag names across all commands
6
+ - Consistent help text
7
+ - No code duplication for common flag patterns
8
+
9
+ Usage:
10
+ from cli.commands.shared_flags import SEARCH, LIMIT, TAGS
11
+
12
+ def my_command(
13
+ search: str | None = SEARCH,
14
+ limit: int = LIMIT,
15
+ tags: str | None = TAGS,
16
+ ) -> None:
17
+ ...
18
+
19
+ Short Flag Convention:
20
+ -a --agent Agent name/UUID
21
+ -c --content Inline content
22
+ -d --description Description field
23
+ -e --export Export format
24
+ -f --file Input file path
25
+ -g --group-by Group results by field
26
+ -l --limit Result limit
27
+ -m --message User message
28
+ -n --name Name field
29
+ -o --output Output mode (console/clipboard/file)
30
+ -O --output-file Output file path (capital O)
31
+ -p --provider Provider key
32
+ -M --model Model name (capital M, avoids -m message conflict)
33
+ -s --search Search query
34
+ -t --tags Tags (comma-separated)
35
+ -T --temperature Temperature parameter (capital T)
36
+ -v --var Template variable
37
+ -V --visibility Visibility level (capital V)
38
+ -w --where Filter condition
39
+ -x --exclude Exclude pattern
40
+ -y --yes Skip confirmation (replaces --force)
41
+ """
42
+
43
+ from typing import Annotated, Optional
44
+
45
+ import typer
46
+
47
+ # =============================================================================
48
+ # PAGINATION FLAGS
49
+ # =============================================================================
50
+
51
+ LIMIT = typer.Option(
52
+ 50,
53
+ "-l",
54
+ "--limit",
55
+ min=1,
56
+ max=100,
57
+ help="Max results to return",
58
+ )
59
+
60
+ OFFSET = typer.Option(
61
+ 0,
62
+ "--offset",
63
+ min=0,
64
+ help="Skip N results",
65
+ )
66
+
67
+ CURSOR = typer.Option(
68
+ None,
69
+ "--cursor",
70
+ help="Pagination cursor from previous response",
71
+ )
72
+
73
+
74
+ # =============================================================================
75
+ # SEARCH FLAGS
76
+ # =============================================================================
77
+
78
+ SEARCH = typer.Option(
79
+ None,
80
+ "-s",
81
+ "--search",
82
+ help="Fuzzy search terms",
83
+ )
84
+
85
+
86
+ # =============================================================================
87
+ # OUTPUT FLAGS
88
+ # =============================================================================
89
+
90
+ OUTPUT_MODE = typer.Option(
91
+ "console",
92
+ "-o",
93
+ "--output",
94
+ help="Output: console, clipboard, or file",
95
+ )
96
+
97
+ OUTPUT_FILE = typer.Option(
98
+ None,
99
+ "-O",
100
+ "--output-file",
101
+ help="Output file path (for --output file)",
102
+ )
103
+
104
+
105
+ # =============================================================================
106
+ # CONTENT INPUT FLAGS
107
+ # =============================================================================
108
+
109
+ FILE_INPUT = typer.Option(
110
+ None,
111
+ "-f",
112
+ "--file",
113
+ help="Read content from file",
114
+ exists=True,
115
+ readable=True,
116
+ )
117
+
118
+ CONTENT_INLINE = typer.Option(
119
+ None,
120
+ "-c",
121
+ "--content",
122
+ help="Inline content (or @file to read from file)",
123
+ )
124
+
125
+
126
+ # =============================================================================
127
+ # COMMON ENTITY FLAGS
128
+ # =============================================================================
129
+
130
+ NAME = typer.Option(
131
+ ...,
132
+ "-n",
133
+ "--name",
134
+ help="Name",
135
+ )
136
+
137
+ NAME_OPTIONAL = typer.Option(
138
+ None,
139
+ "-n",
140
+ "--name",
141
+ help="Name",
142
+ )
143
+
144
+ DESCRIPTION = typer.Option(
145
+ None,
146
+ "-d",
147
+ "--description",
148
+ help="Description",
149
+ )
150
+
151
+ TAGS = typer.Option(
152
+ None,
153
+ "-t",
154
+ "--tags",
155
+ help="Comma-separated tags",
156
+ )
157
+
158
+ TAGS_REQUIRED = typer.Option(
159
+ ...,
160
+ "-t",
161
+ "--tags",
162
+ help="Comma-separated tags",
163
+ )
164
+
165
+ TAGS_LIST = Annotated[
166
+ Optional[list[str]],
167
+ typer.Option(
168
+ "-t",
169
+ "--tag",
170
+ help="Tag to include (repeatable)",
171
+ ),
172
+ ]
173
+
174
+ EXCLUDE_TAGS = Annotated[
175
+ Optional[list[str]],
176
+ typer.Option(
177
+ "-x",
178
+ "--exclude",
179
+ help="Tag pattern to exclude (repeatable)",
180
+ ),
181
+ ]
182
+
183
+
184
+ # =============================================================================
185
+ # CONFIRMATION FLAGS
186
+ # =============================================================================
187
+
188
+ YES = typer.Option(
189
+ False,
190
+ "-y",
191
+ "--yes",
192
+ help="Skip confirmation prompt",
193
+ )
194
+
195
+ # =============================================================================
196
+ # MODEL SELECTION FLAGS
197
+ # =============================================================================
198
+
199
+ AGENT = typer.Option(
200
+ None,
201
+ "-a",
202
+ "--agent",
203
+ help="Agent name or UUID",
204
+ )
205
+
206
+ AGENT_REQUIRED = typer.Option(
207
+ ...,
208
+ "-a",
209
+ "--agent",
210
+ help="Agent name or UUID",
211
+ )
212
+
213
+ PROVIDER = typer.Option(
214
+ None,
215
+ "-p",
216
+ "--provider",
217
+ help="Provider key (anthropic, openai, etc.)",
218
+ )
219
+
220
+ PROVIDER_REQUIRED = typer.Option(
221
+ ...,
222
+ "-p",
223
+ "--provider",
224
+ help="Provider key (anthropic, openai, etc.)",
225
+ )
226
+
227
+ MODEL = typer.Option(
228
+ None,
229
+ "-M",
230
+ "--model",
231
+ help="Model name",
232
+ )
233
+
234
+ MODEL_REQUIRED = typer.Option(
235
+ ...,
236
+ "-M",
237
+ "--model",
238
+ help="Model name",
239
+ )
240
+
241
+
242
+ # =============================================================================
243
+ # GENERATION PARAMETER FLAGS
244
+ # =============================================================================
245
+
246
+ TEMPERATURE = typer.Option(
247
+ None,
248
+ "-T",
249
+ "--temperature",
250
+ help="Temperature (0.0-2.0)",
251
+ )
252
+
253
+ MAX_TOKENS = typer.Option(
254
+ None,
255
+ "--max-tokens",
256
+ help="Max tokens to generate",
257
+ )
258
+
259
+ REASONING_EFFORT = typer.Option(
260
+ None,
261
+ "--reasoning-effort",
262
+ help="Reasoning: none|minimal|low|medium|high",
263
+ )
264
+
265
+
266
+ # =============================================================================
267
+ # MESSAGE FLAGS
268
+ # =============================================================================
269
+
270
+ MESSAGE = typer.Option(
271
+ None,
272
+ "-m",
273
+ "--message",
274
+ help="User message (or @file)",
275
+ )
276
+
277
+ MESSAGE_REQUIRED = typer.Option(
278
+ ...,
279
+ "-m",
280
+ "--message",
281
+ help="User message (or @file)",
282
+ )
283
+
284
+ SYSTEM_INSTRUCTION = typer.Option(
285
+ None,
286
+ "--system",
287
+ help="System instruction (or @file)",
288
+ )
289
+
290
+
291
+ # =============================================================================
292
+ # TEMPLATE FLAGS
293
+ # =============================================================================
294
+
295
+ TEMPLATE_VAR = Annotated[
296
+ Optional[list[str]],
297
+ typer.Option(
298
+ "-v",
299
+ "--var",
300
+ help="Variable (key=value or key:=json). Repeatable.",
301
+ ),
302
+ ]
303
+
304
+ VISIBILITY = typer.Option(
305
+ None,
306
+ "-V",
307
+ "--visibility",
308
+ help="Visibility: private, organization, public",
309
+ )
310
+
311
+ VISIBILITY_REQUIRED = typer.Option(
312
+ ...,
313
+ "-V",
314
+ "--visibility",
315
+ help="Visibility: private, organization, public",
316
+ )
317
+
318
+ CONTENT_TYPE = typer.Option(
319
+ None,
320
+ "--type",
321
+ help="Content type",
322
+ )
323
+
324
+ CONTENT_TYPE_REQUIRED = typer.Option(
325
+ ...,
326
+ "--type",
327
+ help="Content type",
328
+ )
329
+
330
+
331
+ # =============================================================================
332
+ # SCOPE FLAGS
333
+ # =============================================================================
334
+
335
+ SCOPE = typer.Option(
336
+ None,
337
+ "--scope",
338
+ help="Scope: user, organization, global",
339
+ )
340
+
341
+
342
+ # =============================================================================
343
+ # EXPORT FLAGS
344
+ # =============================================================================
345
+
346
+ EXPORT_FORMAT = typer.Option(
347
+ None,
348
+ "-e",
349
+ "--export",
350
+ help="Export format: markdown, xml, json, plain",
351
+ )
352
+
353
+ GROUP_BY = typer.Option(
354
+ None,
355
+ "-g",
356
+ "--group-by",
357
+ help="Group results by field",
358
+ )
359
+
360
+
361
+ # =============================================================================
362
+ # FILTER FLAGS
363
+ # =============================================================================
364
+
365
+ WHERE = Annotated[
366
+ Optional[list[str]],
367
+ typer.Option(
368
+ "-w",
369
+ "--where",
370
+ help="Filter: field=value, field>=num. Repeatable.",
371
+ ),
372
+ ]
373
+
374
+
375
+ # =============================================================================
376
+ # SESSION FLAGS
377
+ # =============================================================================
378
+
379
+ SESSION_ID = typer.Option(
380
+ None,
381
+ "--session",
382
+ help="Session ID to resume",
383
+ )
384
+
385
+ SESSION_NAME = typer.Option(
386
+ None,
387
+ "-n",
388
+ "--name",
389
+ help="Name for new session",
390
+ )
391
+
392
+
393
+ # =============================================================================
394
+ # SCHEMA FLAGS
395
+ # =============================================================================
396
+
397
+ SCHEMA_REF = typer.Option(
398
+ None,
399
+ "--schema",
400
+ help="Schema name or UUID",
401
+ )
402
+
403
+ SCHEMA_FORMAT = typer.Option(
404
+ None,
405
+ "--schema-format",
406
+ help="Schema format: json_schema, regex",
407
+ )
408
+
409
+ SCHEMA_DEF = typer.Option(
410
+ None,
411
+ "--schema-def",
412
+ help="Schema definition (or @file)",
413
+ )
414
+
415
+
416
+ # =============================================================================
417
+ # CLEAR FLAGS (for update commands)
418
+ # =============================================================================
419
+
420
+ CLEAR_DESCRIPTION = typer.Option(
421
+ False,
422
+ "--clear-description",
423
+ help="Clear the description",
424
+ )
425
+
426
+ CLEAR_TAGS = typer.Option(
427
+ False,
428
+ "--clear-tags",
429
+ help="Remove all tags",
430
+ )
431
+
432
+
433
+ # =============================================================================
434
+ # DISPLAY FLAGS
435
+ # =============================================================================
436
+
437
+ FULL_OUTPUT = typer.Option(
438
+ False,
439
+ "--full",
440
+ help="Show full content (no truncation)",
441
+ )
442
+
443
+ COPY_TO_CLIPBOARD = typer.Option(
444
+ False,
445
+ "--copy",
446
+ help="Copy to clipboard",
447
+ )
448
+
449
+ STREAM = typer.Option(
450
+ True,
451
+ "--stream/--no-stream",
452
+ help="Stream output",
453
+ )
454
+
455
+ SHOW_THINKING = typer.Option(
456
+ True,
457
+ "--thinking/--no-thinking",
458
+ help="Show thinking blocks",
459
+ )
460
+
461
+
462
+ # =============================================================================
463
+ # CREDENTIAL FLAGS
464
+ # =============================================================================
465
+
466
+ CREDENTIAL_VALUE = typer.Option(
467
+ ...,
468
+ "--value",
469
+ help="API key value (will be encrypted)",
470
+ )
471
+
472
+ CREDENTIAL_VALUE_OPTIONAL = typer.Option(
473
+ None,
474
+ "--value",
475
+ help="API key value (will be encrypted)",
476
+ )
477
+
478
+
479
+ # =============================================================================
480
+ # COUNT/CONCURRENT FLAGS
481
+ # =============================================================================
482
+
483
+ COUNT = typer.Option(
484
+ 1,
485
+ "--count",
486
+ min=1,
487
+ max=10,
488
+ help="Number of concurrent executions",
489
+ )
490
+
491
+
492
+ # =============================================================================
493
+ # UPSERT FLAG
494
+ # =============================================================================
495
+
496
+ UPSERT = typer.Option(
497
+ False,
498
+ "--upsert",
499
+ help="Return existing if name already exists",
500
+ )
File without changes
@@ -0,0 +1,45 @@
1
+ """Sync command implementation - simplified."""
2
+
3
+ from cli.commands.sync.presenter import present_sync_models_success
4
+ from cli.infrastructure.command import async_command, authenticated_client
5
+ from cli.infrastructure.console import get_console
6
+
7
+
8
+ def sync_command() -> None:
9
+ """Sync AI models from provider sources.
10
+
11
+ Requires system admin privileges. This command pulls the latest model
12
+ information from configured AI providers and updates the local database.
13
+
14
+ The sync process:
15
+ 1. Fetches models from Models.dev API
16
+ 2. Fetches models from OpenRouter API
17
+ 3. Upserts providers and provider models to database
18
+ 4. Uses exact provider model names (no canonical name mapping)
19
+
20
+ Example:
21
+ ai2 sync models
22
+
23
+ Note:
24
+ This is an admin-only operation that requires appropriate credentials.
25
+ """
26
+ _execute_sync()
27
+
28
+
29
+ @async_command
30
+ async def _execute_sync() -> None:
31
+ """Execute sync operation.
32
+
33
+ Raises:
34
+ ConfigurationError: If environment variables are missing
35
+ AuthenticationError: If API key is invalid
36
+ ForbiddenError: If user lacks admin privileges
37
+ ServerError: If server returns 5xx error
38
+ """
39
+ console = get_console()
40
+ console.print("[bold blue]Fetching models from providers...[/]")
41
+
42
+ async with authenticated_client() as (_config, client):
43
+ response = await client.sync_models()
44
+
45
+ present_sync_models_success(response)
@@ -0,0 +1,49 @@
1
+ """Presenter for sync command output."""
2
+
3
+ from rich.table import Table
4
+ from alloy_runtime_types.dtos.admin import SyncModelsResponse
5
+
6
+ from cli.infrastructure.console import get_console
7
+ from cli.infrastructure.output import print_success
8
+
9
+
10
+ def present_sync_models_success(response: SyncModelsResponse) -> None:
11
+ """Present successful model sync results with Rich formatting.
12
+
13
+ Args:
14
+ response: Sync results from server
15
+ """
16
+ console = get_console()
17
+
18
+ # Print success message with summary
19
+ print_success(
20
+ f"Synced {response.total_models_synced} models from {response.total_providers_synced} providers"
21
+ )
22
+
23
+ # Create table for per-source breakdown
24
+ if response.by_source:
25
+ table = Table(
26
+ title="Sync Results by Source",
27
+ show_header=True,
28
+ header_style="bold magenta",
29
+ )
30
+ table.add_column("Source", style="cyan", no_wrap=True)
31
+ table.add_column("Models", style="white", justify="right")
32
+ table.add_column("Providers", style="white", justify="right")
33
+ table.add_column("Status", style="white")
34
+
35
+ # Add rows for each source
36
+ for source_name, result in response.by_source.items():
37
+ if result.error:
38
+ status = f"[red]✗ {result.error}[/red]"
39
+ else:
40
+ status = "[green]✓ Success[/green]"
41
+
42
+ table.add_row(
43
+ source_name,
44
+ str(result.models_synced),
45
+ str(result.providers_synced),
46
+ status,
47
+ )
48
+
49
+ console.print(table)
@@ -0,0 +1 @@
1
+ # Empty per project convention - import directly from submodules
@@ -0,0 +1 @@
1
+ # Empty per project convention - import directly from submodules
@@ -0,0 +1,60 @@
1
+ """Tag create command implementation."""
2
+
3
+ from typing import Optional
4
+
5
+ import typer
6
+
7
+ from cli.infrastructure.command import async_command, authenticated_client
8
+ from cli.infrastructure.output import OutputService
9
+
10
+ from alloy_runtime_types.dtos.tags import CreateTagRequest
11
+
12
+
13
+ def tags_create_command(
14
+ tag_path: str = typer.Argument(
15
+ ...,
16
+ help="Hierarchical tag path (e.g., 'marketing.email.weekly')",
17
+ ),
18
+ display_name: Optional[str] = typer.Option(
19
+ None,
20
+ "-n",
21
+ "--name",
22
+ help="Human-friendly display name",
23
+ ),
24
+ description: Optional[str] = typer.Option(
25
+ None,
26
+ "-d",
27
+ "--description",
28
+ help="Tag description",
29
+ ),
30
+ ) -> None:
31
+ """Create a new tag.
32
+
33
+ Examples:
34
+ ai tags create marketing.email
35
+ ai tags create marketing.email.weekly -n "Weekly Emails"
36
+ """
37
+ _execute_create(
38
+ tag_path=tag_path,
39
+ display_name=display_name,
40
+ description=description,
41
+ )
42
+
43
+
44
+ @async_command
45
+ async def _execute_create(
46
+ tag_path: str,
47
+ display_name: Optional[str],
48
+ description: Optional[str],
49
+ ) -> None:
50
+ """Execute create tag operation."""
51
+ async with authenticated_client() as (_config, client):
52
+ request = CreateTagRequest(
53
+ tag_path=tag_path,
54
+ display_name=display_name,
55
+ description=description,
56
+ )
57
+ response = await client.create_tag(request)
58
+
59
+ output = OutputService.get()
60
+ output.success(f"Created tag: {response.tag.tag_path}")
@@ -0,0 +1 @@
1
+ # Empty per project convention - import directly from submodules
@@ -0,0 +1,47 @@
1
+ """Tag delete command implementation."""
2
+
3
+ from uuid import UUID
4
+
5
+ import typer
6
+
7
+ from cli.commands.flag_utils import validate_uuid
8
+ from cli.commands.tags.delete.presenter import present_delete_result
9
+ from cli.infrastructure.command import async_command, authenticated_client
10
+ from cli.infrastructure.console import Confirm
11
+
12
+
13
+ def tags_delete_command(
14
+ tag_id: str = typer.Argument(
15
+ ...,
16
+ help="Tag UUID",
17
+ ),
18
+ yes: bool = typer.Option(
19
+ False,
20
+ "-y",
21
+ "--yes",
22
+ help="Skip confirmation",
23
+ ),
24
+ ) -> None:
25
+ """Delete a tag.
26
+
27
+ Examples:
28
+ ai tags delete 123e4567-89ab-cdef-0123-456789abcdef
29
+ ai tags delete 123e4567-89ab... -y
30
+ """
31
+ tag_uuid = validate_uuid(tag_id, "tag")
32
+
33
+ if not yes:
34
+ confirmed = Confirm.ask(f"[yellow]Delete tag {tag_id}?[/yellow]")
35
+ if not confirmed:
36
+ raise typer.Abort()
37
+
38
+ _execute_delete(tag_id=tag_uuid)
39
+
40
+
41
+ @async_command
42
+ async def _execute_delete(tag_id: UUID) -> None:
43
+ """Execute delete tag operation."""
44
+ async with authenticated_client() as (_config, client):
45
+ response = await client.delete_tag(tag_id)
46
+
47
+ present_delete_result(response)