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,308 @@
1
+ """Template update modal for editing existing template metadata.
2
+
3
+ Provides a modal screen that allows users to edit template name, description,
4
+ content type, visibility, and tags.
5
+ """
6
+
7
+ import re
8
+ from dataclasses import dataclass
9
+ from typing import TYPE_CHECKING, Any
10
+
11
+ from textual import on, work
12
+ from textual.app import ComposeResult
13
+ from textual.containers import Horizontal, VerticalScroll
14
+ from textual.widgets import (
15
+ Button,
16
+ Input,
17
+ Label,
18
+ RadioButton,
19
+ RadioSet,
20
+ Static,
21
+ )
22
+
23
+ from cli.tui.widgets.base_form_modal import BaseFormModal
24
+
25
+ from alloy_runtime_sdk.api_client.client import ApiClient
26
+ from alloy_runtime_types.dtos.templates import (
27
+ TemplateListItemResponse,
28
+ UpdateTemplateRequest,
29
+ )
30
+ from alloy_runtime_types.enums.template_enums import (
31
+ TemplateContentType,
32
+ TemplateVisibility,
33
+ )
34
+
35
+ from cli.infrastructure.forms.tag_picker import TagPicker
36
+
37
+ if TYPE_CHECKING:
38
+ from cli.tui.app import AlloyRuntimeApp
39
+
40
+
41
+ @dataclass
42
+ class TemplateUpdateResult:
43
+ """Result of successful template update."""
44
+
45
+ template_id: str
46
+ template_name: str
47
+
48
+
49
+ class TemplateUpdateModal(BaseFormModal[TemplateUpdateResult]):
50
+ """Modal for updating template metadata.
51
+
52
+ Provides a form with:
53
+ - Editable fields: name, content type, visibility, description, tags
54
+ - Read-only info: ID, version count
55
+
56
+ Usage:
57
+ def on_template_updated(result: TemplateUpdateResult | None):
58
+ if result is not None:
59
+ self.notify(f"Updated template: {result.template_name}")
60
+ self._do_search("") # Refresh list
61
+
62
+ client = await self.app.store.get_client()
63
+ self.app.push_screen(
64
+ TemplateUpdateModal(client=client, template=template),
65
+ on_template_updated
66
+ )
67
+ """
68
+
69
+ app: "AlloyRuntimeApp"
70
+
71
+ def __init__(
72
+ self,
73
+ client: ApiClient,
74
+ template: TemplateListItemResponse,
75
+ **kwargs: Any,
76
+ ) -> None:
77
+ """Initialize the template update modal.
78
+
79
+ Args:
80
+ client: ApiClient instance for API calls
81
+ template: The template to edit
82
+ """
83
+ super().__init__(**kwargs)
84
+ self._client = client
85
+ self._template = template
86
+
87
+ def compose(self) -> ComposeResult:
88
+ with VerticalScroll(id="template-update-modal"):
89
+ yield Label(f"Edit Template: {self._template.name}", classes="modal-title")
90
+
91
+ # Template info (read-only)
92
+ yield Static("[bold]Template Info[/]", classes="form-section")
93
+
94
+ yield Static(
95
+ f"[dim]ID:[/] {str(self._template.id)[:8]}... "
96
+ f"[dim]Versions:[/] {self._template.latest_version_number}",
97
+ id="template-info",
98
+ classes="info-display",
99
+ )
100
+
101
+ # Editable fields
102
+ yield Static("[bold]Edit Properties[/]", classes="form-section")
103
+
104
+ yield Static(
105
+ "Name (lowercase, dots/dashes/underscores)", classes="field-label"
106
+ )
107
+ yield Input(
108
+ value=self._template.name,
109
+ placeholder="e.g., email.welcome-header, system.default_prompt",
110
+ id="name-input",
111
+ )
112
+
113
+ yield Static("Content Type", classes="field-label")
114
+ with RadioSet(id="content-type-radios"):
115
+ yield RadioButton(
116
+ "System Instruction",
117
+ id="type-system",
118
+ value=self._template.content_type_id == "system_instruction",
119
+ )
120
+ yield RadioButton(
121
+ "User Message",
122
+ id="type-user",
123
+ value=self._template.content_type_id == "user_message",
124
+ )
125
+ yield RadioButton(
126
+ "Fragment",
127
+ id="type-fragment",
128
+ value=self._template.content_type_id == "fragment",
129
+ )
130
+
131
+ yield Static("Visibility", classes="field-label")
132
+ with RadioSet(id="visibility-radios"):
133
+ yield RadioButton(
134
+ "Private",
135
+ id="vis-private",
136
+ value=self._template.visibility_id == "private",
137
+ )
138
+ yield RadioButton(
139
+ "Organization",
140
+ id="vis-org",
141
+ value=self._template.visibility_id == "organization",
142
+ )
143
+ yield RadioButton(
144
+ "Public",
145
+ id="vis-public",
146
+ value=self._template.visibility_id == "public",
147
+ )
148
+
149
+ yield Static("Description", classes="field-label")
150
+ yield Input(
151
+ value=self._template.description or "",
152
+ placeholder="Brief description of this template's purpose",
153
+ id="description-input",
154
+ )
155
+
156
+ yield Static("Tags", classes="field-label")
157
+ yield TagPicker(
158
+ client=self._client,
159
+ placeholder="Search tags...",
160
+ empty_message="No tags selected",
161
+ id="tag-picker",
162
+ )
163
+
164
+ # Error display
165
+ yield Static("", id="error-display", classes="error-display")
166
+
167
+ with Horizontal(classes="button-row"):
168
+ yield Button("Update Template", id="update-btn", variant="success")
169
+ yield Button("Cancel", id="cancel-btn", variant="default")
170
+
171
+ def on_mount(self) -> None:
172
+ """Focus the name input and populate tags on mount."""
173
+ self.query_one("#name-input", Input).focus()
174
+ self._populate_tags()
175
+
176
+ def _populate_tags(self) -> None:
177
+ """Populate the tag picker with existing tags."""
178
+ tag_picker = self.query_one("#tag-picker", TagPicker)
179
+ existing_tags = [
180
+ {"tag_path": t.tag_path, "display_name": t.display_name}
181
+ for t in self._template.tags
182
+ ]
183
+ if existing_tags:
184
+ tag_picker.set_initial_selection(existing_tags)
185
+
186
+ @on(Button.Pressed, "#update-btn")
187
+ def on_update_pressed(self, event: Button.Pressed) -> None:
188
+ """Handle update button press."""
189
+ self.action_submit()
190
+
191
+ @on(Button.Pressed, "#cancel-btn")
192
+ def on_cancel_pressed(self, event: Button.Pressed) -> None:
193
+ """Handle cancel button press."""
194
+ self.dismiss(None)
195
+
196
+ def action_submit(self) -> None:
197
+ """Handle form submission."""
198
+ try:
199
+ self._validate_fields()
200
+ self._hide_error()
201
+ self._finalize_submission()
202
+ except ValueError as e:
203
+ self._show_error(str(e))
204
+
205
+ def _validate_fields(self) -> None:
206
+ """Validate all required fields."""
207
+ name = self.query_one("#name-input", Input).value.strip()
208
+ if not name:
209
+ raise ValueError("Name is required")
210
+
211
+ if not re.match(r"^[a-z0-9._-]+$", name):
212
+ raise ValueError(
213
+ "Name must be lowercase alphanumeric with dots, dashes, or underscores only"
214
+ )
215
+
216
+ def _get_content_type(self) -> TemplateContentType:
217
+ """Get content type from RadioSet."""
218
+ radios = self.query_one("#content-type-radios", RadioSet)
219
+ pressed = radios.pressed_button
220
+ if pressed is None or pressed.id == "type-system":
221
+ return TemplateContentType.SYSTEM_INSTRUCTION
222
+ elif pressed.id == "type-user":
223
+ return TemplateContentType.USER_MESSAGE
224
+ else:
225
+ return TemplateContentType.FRAGMENT
226
+
227
+ def _get_visibility(self) -> TemplateVisibility:
228
+ """Get visibility from RadioSet."""
229
+ radios = self.query_one("#visibility-radios", RadioSet)
230
+ pressed = radios.pressed_button
231
+ if pressed is None or pressed.id == "vis-private":
232
+ return TemplateVisibility.PRIVATE
233
+ elif pressed.id == "vis-org":
234
+ return TemplateVisibility.ORGANIZATION
235
+ else:
236
+ return TemplateVisibility.PUBLIC
237
+
238
+ def _build_request(self) -> UpdateTemplateRequest:
239
+ """Build the API request with only changed fields."""
240
+ name = self.query_one("#name-input", Input).value.strip()
241
+ description = self.query_one("#description-input", Input).value.strip()
242
+ content_type = self._get_content_type()
243
+ visibility = self._get_visibility()
244
+
245
+ tag_picker = self.query_one("#tag-picker", TagPicker)
246
+ new_tag_paths = tag_picker.selected_tags
247
+ old_tag_paths = [t.tag_path for t in self._template.tags]
248
+
249
+ # Only include fields that have changed
250
+ request_name = name if name != self._template.name else None
251
+
252
+ request_description: str | None = None
253
+ old_description = self._template.description or ""
254
+ if description != old_description:
255
+ request_description = description # Empty string clears description
256
+
257
+ request_content_type = (
258
+ content_type
259
+ if content_type.value != self._template.content_type_id
260
+ else None
261
+ )
262
+ request_visibility = (
263
+ visibility if visibility.value != self._template.visibility_id else None
264
+ )
265
+
266
+ # Compare tag lists (order-insensitive)
267
+ request_tag_paths = (
268
+ new_tag_paths if sorted(new_tag_paths) != sorted(old_tag_paths) else None
269
+ )
270
+
271
+ return UpdateTemplateRequest(
272
+ name=request_name,
273
+ content_type=request_content_type,
274
+ visibility=request_visibility,
275
+ description=request_description,
276
+ tag_paths=request_tag_paths,
277
+ )
278
+
279
+ @work(exclusive=True)
280
+ async def _finalize_submission(self) -> None:
281
+ """Submit to API."""
282
+ try:
283
+ request = self._build_request()
284
+
285
+ # Check if anything actually changed
286
+ if (
287
+ request.name is None
288
+ and request.content_type is None
289
+ and request.visibility is None
290
+ and request.description is None
291
+ and request.tag_paths is None
292
+ ):
293
+ self.app.notify("No changes made", severity="information")
294
+ self.dismiss(None)
295
+ return
296
+
297
+ response = await self._client.update_template(
298
+ str(self._template.id), request
299
+ )
300
+
301
+ result = TemplateUpdateResult(
302
+ template_id=str(response.template.id),
303
+ template_name=response.template.name,
304
+ )
305
+ self.dismiss(result)
306
+
307
+ except Exception as e:
308
+ self._show_error(f"Failed to update template: {e}")
@@ -0,0 +1,216 @@
1
+ """Tool config creation modal for creating new tool configurations.
2
+
3
+ Provides a modal screen that allows users to create a new tool configuration
4
+ with required fields: name, tool_id, config JSON, and optional description.
5
+ """
6
+
7
+ import json
8
+ from dataclasses import dataclass
9
+ from typing import Any
10
+
11
+ from textual import on, work
12
+ from textual.app import ComposeResult
13
+ from textual.containers import Horizontal, VerticalScroll
14
+ from textual.widgets import (
15
+ Button,
16
+ Input,
17
+ Label,
18
+ RadioButton,
19
+ RadioSet,
20
+ Static,
21
+ TextArea,
22
+ )
23
+
24
+ from cli.infrastructure.scope_utils import get_scope_from_radioset
25
+ from cli.tui.widgets.base_form_modal import BaseFormModal
26
+
27
+ from alloy_runtime_sdk.api_client.client import ApiClient
28
+ from alloy_runtime_types.dtos.tool_configs import CreateToolConfigRequest
29
+ from alloy_runtime_types.enums.ownership_scope import OwnershipScope
30
+
31
+
32
+ @dataclass
33
+ class ToolConfigCreateResult:
34
+ """Result of successful tool config creation."""
35
+
36
+ config_id: str
37
+ config_name: str
38
+
39
+
40
+ class ToolConfigCreateModal(BaseFormModal[ToolConfigCreateResult]):
41
+ """Modal for creating a new tool configuration.
42
+
43
+ Provides a form with:
44
+ - Required fields: name, tool_id, config (JSON)
45
+ - Scope selection (user/organization/global)
46
+ - Optional: description
47
+
48
+ Usage:
49
+ def on_config_created(result: ToolConfigCreateResult | None):
50
+ if result is not None:
51
+ self.notify(f"Created config: {result.config_name}")
52
+ self._do_search("") # Refresh list
53
+
54
+ client = await self.app.store.get_client()
55
+ self.app.push_screen(
56
+ ToolConfigCreateModal(client=client),
57
+ on_config_created
58
+ )
59
+ """
60
+
61
+ def __init__(
62
+ self,
63
+ client: ApiClient,
64
+ **kwargs: Any,
65
+ ) -> None:
66
+ """Initialize the tool config creation modal.
67
+
68
+ Args:
69
+ client: ApiClient instance for API calls
70
+ """
71
+ super().__init__(**kwargs)
72
+ self._client = client
73
+
74
+ def compose(self) -> ComposeResult:
75
+ with VerticalScroll(id="tool-config-create-modal"):
76
+ yield Label("Create Tool Config", classes="modal-title")
77
+
78
+ # ===== REQUIRED FIELDS =====
79
+ yield Static("[bold]Required[/]", classes="form-section")
80
+
81
+ yield Static("Name", classes="field-label")
82
+ yield Input(
83
+ placeholder="e.g., RAG with HyDE, Fast Web Search",
84
+ id="name-input",
85
+ )
86
+
87
+ yield Static("Tool ID", classes="field-label")
88
+ yield Input(
89
+ placeholder="e.g., rag_search, web_search",
90
+ id="tool-id-input",
91
+ )
92
+
93
+ yield Static("Scope", classes="field-label")
94
+ with RadioSet(id="scope-radios"):
95
+ yield RadioButton("User (personal)", id="scope-user", value=True)
96
+ yield RadioButton("Organization", id="scope-org")
97
+ yield RadioButton("Global", id="scope-global")
98
+
99
+ yield Static(
100
+ "Configuration (JSON object with tool parameters)",
101
+ classes="field-label",
102
+ )
103
+ yield TextArea(
104
+ id="config-textarea",
105
+ classes="definition-input",
106
+ )
107
+
108
+ # ===== OPTIONAL FIELDS =====
109
+ yield Static("[bold]Optional[/]", classes="form-section")
110
+
111
+ yield Static("Description", classes="field-label")
112
+ yield Input(
113
+ placeholder="Brief description of this configuration",
114
+ id="description-input",
115
+ )
116
+
117
+ # Error display
118
+ yield Static("", id="error-display", classes="error-display")
119
+
120
+ with Horizontal(classes="button-row"):
121
+ yield Button("Create Config", id="create-btn", variant="success")
122
+ yield Button("Cancel", id="cancel-btn", variant="default")
123
+
124
+ def on_mount(self) -> None:
125
+ """Focus the name input and set default config on mount."""
126
+ self.query_one("#config-textarea", TextArea).text = "{}"
127
+ self.query_one("#name-input", Input).focus()
128
+
129
+ @on(Button.Pressed, "#create-btn")
130
+ def on_create_pressed(self, event: Button.Pressed) -> None:
131
+ """Handle create button press."""
132
+ self.action_submit()
133
+
134
+ @on(Button.Pressed, "#cancel-btn")
135
+ def on_cancel_pressed(self, event: Button.Pressed) -> None:
136
+ """Handle cancel button press."""
137
+ self.dismiss(None)
138
+
139
+ def action_submit(self) -> None:
140
+ """Handle form submission."""
141
+ try:
142
+ self._validate_fields()
143
+ self._hide_error()
144
+ self._finalize_submission()
145
+ except ValueError as e:
146
+ self._show_error(str(e))
147
+
148
+ def _validate_fields(self) -> None:
149
+ """Validate all required fields."""
150
+ name = self.query_one("#name-input", Input).value.strip()
151
+ if not name:
152
+ raise ValueError("Name is required")
153
+ if len(name) > 255:
154
+ raise ValueError("Name must be 255 characters or less")
155
+
156
+ tool_id = self.query_one("#tool-id-input", Input).value.strip()
157
+ if not tool_id:
158
+ raise ValueError("Tool ID is required")
159
+
160
+ config_text = self.query_one("#config-textarea", TextArea).text.strip()
161
+ if not config_text:
162
+ raise ValueError("Configuration is required")
163
+
164
+ try:
165
+ config = json.loads(config_text)
166
+ if not isinstance(config, dict):
167
+ raise ValueError(
168
+ "Configuration must be a JSON object (not array/primitive)"
169
+ )
170
+ except json.JSONDecodeError as e:
171
+ raise ValueError(f"Invalid JSON in configuration: {e.msg}")
172
+
173
+ def _get_scope(self) -> OwnershipScope:
174
+ """Get scope from RadioSet."""
175
+ return get_scope_from_radioset(self.query_one("#scope-radios", RadioSet))
176
+
177
+ def _build_request(self) -> CreateToolConfigRequest:
178
+ """Build the API request."""
179
+ name = self.query_one("#name-input", Input).value.strip()
180
+ tool_id = self.query_one("#tool-id-input", Input).value.strip()
181
+ config_text = self.query_one("#config-textarea", TextArea).text.strip()
182
+ config = json.loads(config_text)
183
+ description = self.query_one("#description-input", Input).value.strip() or None
184
+
185
+ return CreateToolConfigRequest(
186
+ name=name,
187
+ tool_id=tool_id,
188
+ config=config,
189
+ description=description,
190
+ scope=self._get_scope(),
191
+ )
192
+
193
+ @work(exclusive=True)
194
+ async def _finalize_submission(self) -> None:
195
+ """Submit to API."""
196
+ try:
197
+ request = self._build_request()
198
+ response = await self._client.create_tool_config(request)
199
+
200
+ result = ToolConfigCreateResult(
201
+ config_id=str(response.id),
202
+ config_name=response.name,
203
+ )
204
+ self.dismiss(result)
205
+
206
+ except Exception as e:
207
+ error_msg = str(e)
208
+ # Provide user-friendly error messages
209
+ if "409" in error_msg or "conflict" in error_msg.lower():
210
+ self._show_error(
211
+ "A tool config with this name already exists in this scope"
212
+ )
213
+ elif "validation" in error_msg.lower():
214
+ self._show_error(f"Invalid configuration: {error_msg}")
215
+ else:
216
+ self._show_error(f"Failed to create tool config: {error_msg}")