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,302 @@
1
+ """Resolution modal for macro-to-value resolution.
2
+
3
+ Provides a modal screen that allows users to search and select
4
+ the target for a macro (fragment template or content part).
5
+ """
6
+
7
+ import json
8
+ from typing import Any
9
+
10
+ from textual import on, work
11
+ from textual.app import ComposeResult
12
+ from textual.binding import Binding
13
+ from textual.containers import Vertical
14
+ from textual.screen import ModalScreen
15
+ from textual.widgets import Button, Input, Label, OptionList, Static
16
+ from textual.widgets.option_list import Option
17
+
18
+ from alloy_runtime_sdk.api_client.client import ApiClient
19
+ from alloy_runtime_types.enums.content_enums import ContentStorageType
20
+ from alloy_runtime_types.enums.template_enums import TemplateContentType
21
+ from alloy_runtime_sdk.exceptions.errors import RequestError
22
+
23
+
24
+ class ResolutionModal(ModalScreen[dict[str, Any] | None]):
25
+ """Modal for resolving a macro to a specific template or content part.
26
+
27
+ For fragment macros: searches templates and returns the fragment name
28
+ For text/json macros: searches content parts and returns the UUID
29
+
30
+ Usage:
31
+ def on_resolution_complete(result: dict | None):
32
+ if result:
33
+ # result["value"] is the resolved value (name or UUID)
34
+ # result["display"] is a human-readable display string
35
+ pass
36
+
37
+ self.push_screen(
38
+ ResolutionModal(
39
+ client=server_client,
40
+ macro_type="fragment",
41
+ query="header",
42
+ ),
43
+ on_resolution_complete
44
+ )
45
+ """
46
+
47
+ BINDINGS = [
48
+ Binding("escape", "cancel", "Cancel", show=True),
49
+ Binding("enter", "select", "Select", show=True),
50
+ ]
51
+
52
+ def __init__(
53
+ self,
54
+ client: ApiClient,
55
+ macro_type: str,
56
+ query: str,
57
+ **kwargs: Any,
58
+ ) -> None:
59
+ """Initialize the resolution modal.
60
+
61
+ Args:
62
+ client: ApiClient instance for API calls
63
+ macro_type: Type of macro being resolved (fragment, text, json, schema)
64
+ query: Initial search query from the macro
65
+ """
66
+ super().__init__(**kwargs)
67
+ self._client = client
68
+ self._macro_type = macro_type
69
+ self._initial_query = query
70
+ self._search_results: list[dict[str, Any]] = []
71
+ self._last_query: str = ""
72
+
73
+ def compose(self) -> ComposeResult:
74
+ type_label = {
75
+ "fragment": "Fragment Template",
76
+ "text": "Content Part (Text)",
77
+ "json": "Content Part (JSON)",
78
+ "schema": "Schema (JSON/Regex)",
79
+ }.get(self._macro_type, self._macro_type)
80
+
81
+ with Vertical():
82
+ yield Label(f"Resolve @{self._macro_type}(...)", classes="modal-title")
83
+ yield Static(f"Searching for: {type_label}", classes="macro-info")
84
+ yield Input(
85
+ value=self._initial_query,
86
+ placeholder="Type to search...",
87
+ id="search-input",
88
+ )
89
+ yield OptionList(id="results-list")
90
+ yield Static("Type to search...", classes="status-line", id="status")
91
+ with Vertical(classes="button-row"):
92
+ yield Button("Select", id="select-btn", variant="success")
93
+ yield Button("Skip", id="skip-btn", variant="warning")
94
+
95
+ def on_mount(self) -> None:
96
+ """Focus the search input and trigger initial search."""
97
+ self.query_one("#search-input", Input).focus()
98
+ # Trigger initial search with the query from the macro
99
+ if self._initial_query:
100
+ self._search(self._initial_query)
101
+
102
+ @on(Input.Changed, "#search-input")
103
+ def on_search_changed(self, event: Input.Changed) -> None:
104
+ """Search on input change."""
105
+ query = event.value.strip()
106
+ if query != self._last_query:
107
+ self._last_query = query
108
+ self._search(query)
109
+
110
+ @work(exclusive=True)
111
+ async def _search(self, query: str) -> None:
112
+ """Fetch results from the appropriate API endpoint."""
113
+ status = self.query_one("#status", Static)
114
+ options = self.query_one("#results-list", OptionList)
115
+
116
+ if not query:
117
+ status.update("Type to search...")
118
+ options.clear_options()
119
+ self._search_results = []
120
+ return
121
+
122
+ status.update("Searching...")
123
+
124
+ try:
125
+ if self._macro_type == "fragment":
126
+ results = await self._search_templates(query)
127
+ elif self._macro_type == "schema":
128
+ results = await self._search_schemas(query)
129
+ else:
130
+ results = await self._search_content_parts(query)
131
+
132
+ self._search_results = results
133
+ self._update_options()
134
+
135
+ count = len(results)
136
+ if count == 0:
137
+ status.update("No results found")
138
+ else:
139
+ status.update(f"{count} result{'s' if count != 1 else ''} found")
140
+
141
+ except RequestError as e:
142
+ status.update(f"[red]Error: {e}[/]")
143
+ self._search_results = []
144
+ options.clear_options()
145
+ except Exception as e:
146
+ status.update(f"[red]Error: {e}[/]")
147
+ self._search_results = []
148
+ options.clear_options()
149
+
150
+ async def _search_templates(self, query: str) -> list[dict[str, Any]]:
151
+ """Search for fragment templates."""
152
+ response = await self._client.list_templates(
153
+ search=query,
154
+ content_type=TemplateContentType.FRAGMENT,
155
+ limit=50,
156
+ )
157
+ return [template.model_dump() for template in response.templates]
158
+
159
+ async def _search_content_parts(self, query: str) -> list[dict[str, Any]]:
160
+ """Search for content parts filtered by storage type based on macro type."""
161
+ # Determine storage type filter based on macro type
162
+ # text needs content_text (storage_type=text)
163
+ # json needs content_structured (storage_type=structured)
164
+ storage_type = (
165
+ ContentStorageType.TEXT
166
+ if self._macro_type == "text"
167
+ else ContentStorageType.STRUCTURED
168
+ )
169
+
170
+ response = await self._client.list_content_parts(
171
+ search=query,
172
+ storage_type=storage_type,
173
+ limit=50,
174
+ )
175
+ return [part.model_dump() for part in response.content_parts]
176
+
177
+ async def _search_schemas(self, query: str) -> list[dict[str, Any]]:
178
+ """Search for schemas."""
179
+ response = await self._client.list_schemas(search=query, limit=50)
180
+ return [schema.model_dump() for schema in response.schemas]
181
+
182
+ def _update_options(self) -> None:
183
+ """Update the option list with current search results."""
184
+ options = self.query_one("#results-list", OptionList)
185
+ options.clear_options()
186
+
187
+ for i, item in enumerate(self._search_results):
188
+ display_text = self._format_result(item)
189
+ options.add_option(Option(display_text, id=f"opt-{i}"))
190
+
191
+ if self._search_results:
192
+ options.highlighted = 0
193
+
194
+ def _format_result(self, item: dict[str, Any]) -> str:
195
+ """Format a search result for display."""
196
+ if self._macro_type == "fragment":
197
+ # Template result
198
+ name = item.get("name", "Unknown")
199
+ version = item.get("latest_version_number", "?")
200
+ visibility = item.get("visibility_id", "private")
201
+ vis_label = {"private": "Priv", "organization": "Org", "public": "Pub"}.get(
202
+ visibility, visibility[:4]
203
+ )
204
+ return f"{name} (v{version}) [{vis_label}]"
205
+ elif self._macro_type == "schema":
206
+ # Schema result
207
+ name = item.get("schema_name", "Unknown")
208
+ version = item.get("version", "?")
209
+ format_id = item.get("schema_format_id", "unknown")
210
+ description = item.get("description") or ""
211
+ desc_preview = (
212
+ (
213
+ f" - {description[:30]}..."
214
+ if len(description) > 30
215
+ else f" - {description}"
216
+ )
217
+ if description
218
+ else ""
219
+ )
220
+ return f"{name} (v{version}) [{format_id}]{desc_preview}"
221
+ else:
222
+ # Content part result
223
+ content_type = item.get("content_type_id", "unknown")
224
+ part_id = str(item.get("id", ""))[:8]
225
+
226
+ # Get preview based on storage type
227
+ if self._macro_type == "text":
228
+ content_text = item.get("content_text") or ""
229
+ preview = (
230
+ content_text[:50] + "..."
231
+ if len(content_text) > 50
232
+ else content_text
233
+ )
234
+ preview = preview.replace("\n", " ")
235
+ else: # json
236
+ content_structured = item.get("content_structured")
237
+ if content_structured:
238
+ preview = json.dumps(content_structured)[:50] + "..."
239
+ else:
240
+ preview = "(no structured content)"
241
+
242
+ return f"[{content_type}] {preview} ({part_id}...)"
243
+
244
+ def _get_selected_value(self) -> dict[str, Any] | None:
245
+ """Get the resolved value for the currently selected item."""
246
+ options = self.query_one("#results-list", OptionList)
247
+ if options.highlighted is None:
248
+ return None
249
+
250
+ index = options.highlighted
251
+ if index < 0 or index >= len(self._search_results):
252
+ return None
253
+
254
+ item = self._search_results[index]
255
+
256
+ if self._macro_type == "fragment":
257
+ # Return the fragment NAME (not UUID) - this is what the renderer expects
258
+ return {
259
+ "value": item.get("name"),
260
+ "display": self._format_result(item),
261
+ "item": item,
262
+ }
263
+ elif self._macro_type == "schema":
264
+ # Return the schema NAME - renderer supports name lookups with priority ordering
265
+ return {
266
+ "value": item.get("schema_name"),
267
+ "display": self._format_result(item),
268
+ "item": item,
269
+ }
270
+ else:
271
+ # Return the content part UUID
272
+ return {
273
+ "value": str(item.get("id")),
274
+ "display": self._format_result(item),
275
+ "item": item,
276
+ }
277
+
278
+ @on(OptionList.OptionSelected, "#results-list")
279
+ def on_option_selected(self, event: OptionList.OptionSelected) -> None:
280
+ """Handle double-click or enter on option."""
281
+ self.action_select()
282
+
283
+ def on_button_pressed(self, event: Button.Pressed) -> None:
284
+ """Handle button presses."""
285
+ if event.button.id == "select-btn":
286
+ self.action_select()
287
+ elif event.button.id == "skip-btn":
288
+ self.action_cancel()
289
+
290
+ def action_select(self) -> None:
291
+ """Select the current item and dismiss."""
292
+ result = self._get_selected_value()
293
+ if result:
294
+ self.dismiss(result)
295
+ else:
296
+ # No selection - show feedback
297
+ status = self.query_one("#status", Static)
298
+ status.update("[yellow]Select an item first[/]")
299
+
300
+ def action_cancel(self) -> None:
301
+ """Cancel resolution and dismiss with None."""
302
+ self.dismiss(None)
@@ -0,0 +1,137 @@
1
+ """Schema picker component for selecting input/output schemas.
2
+
3
+ A specialized search picker that uses the ApiClient to fetch schemas
4
+ and returns the selected schema's ID.
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ from alloy_runtime_sdk.api_client.client import ApiClient
10
+
11
+ from cli.infrastructure.forms.base_picker import SingleSelectPicker
12
+
13
+
14
+ def _format_schema(schema: dict[str, Any]) -> str:
15
+ """Format a schema for display in the picker."""
16
+ name = schema.get("schema_name", "Unknown")
17
+ version = schema.get("version", "?")
18
+ schema_format = schema.get("schema_format_id", "unknown")
19
+
20
+ # Determine scope from ownership fields
21
+ user_id = schema.get("user_id")
22
+ org_id = schema.get("organization_id")
23
+ if user_id:
24
+ scope = "User"
25
+ elif org_id:
26
+ scope = "Org"
27
+ else:
28
+ scope = "Global"
29
+
30
+ # Truncate description if present
31
+ description = schema.get("description")
32
+ desc_part = ""
33
+ if description:
34
+ if len(description) > 30:
35
+ description = description[:27] + "..."
36
+ desc_part = f" - {description}"
37
+
38
+ return f"{name} (v{version}) [{schema_format}] {scope}{desc_part}"
39
+
40
+
41
+ class SchemaPicker(SingleSelectPicker[dict[str, Any]]):
42
+ """Schema picker for selecting input or output schemas.
43
+
44
+ Searches schemas via the ApiClient and returns the selected schema's ID.
45
+ User sees friendly schema names with version and format info, not UUIDs.
46
+
47
+ Usage:
48
+ yield SchemaPicker(
49
+ client=server_client,
50
+ id="output-schema",
51
+ )
52
+
53
+ # Get selected schema ID
54
+ picker = self.query_one("#output-schema", SchemaPicker)
55
+ schema_id = picker.selected_id # UUID string or None
56
+
57
+ # Optionally filter by format
58
+ yield SchemaPicker(
59
+ client=server_client,
60
+ schema_format="json_schema", # Only show JSON schemas
61
+ id="output-schema",
62
+ )
63
+ """
64
+
65
+ def __init__(
66
+ self,
67
+ client: ApiClient,
68
+ schema_format: str | None = None,
69
+ placeholder: str = "Search schemas (e.g., user profile, json output)...",
70
+ empty_message: str = "No schema selected (optional)",
71
+ **kwargs: Any,
72
+ ) -> None:
73
+ """Initialize the schema picker.
74
+
75
+ Args:
76
+ client: ApiClient instance for API calls
77
+ schema_format: Optional filter by schema format (json_schema or regex)
78
+ placeholder: Placeholder text for search input
79
+ empty_message: Message shown when nothing is selected
80
+ """
81
+ super().__init__(
82
+ client=client,
83
+ placeholder=placeholder,
84
+ empty_message=empty_message,
85
+ **kwargs,
86
+ )
87
+ self._schema_format = schema_format
88
+
89
+ @property
90
+ def selected_schema_id(self) -> str | None:
91
+ """Alias for selected_id - returns the schema UUID."""
92
+ return self.selected_id
93
+
94
+ @property
95
+ def selected_schema_name(self) -> str | None:
96
+ """Get the name of the selected schema."""
97
+ if self._selected_item is None:
98
+ return None
99
+ return self._selected_item.get("schema_name")
100
+
101
+ async def _fetch_items(self, query: str) -> list[dict[str, Any]]:
102
+ """Fetch schemas matching query from the API."""
103
+ response = await self._client.list_schemas(
104
+ search=query,
105
+ schema_format=self._schema_format,
106
+ limit=50,
107
+ )
108
+ return [schema.model_dump() for schema in response.schemas]
109
+
110
+ def _format_item(self, item: dict[str, Any]) -> str:
111
+ """Format schema for display in option list."""
112
+ return _format_schema(item)
113
+
114
+ def _get_item_id(self, item: dict[str, Any]) -> str:
115
+ """Get unique identifier for a schema."""
116
+ return str(item.get("id", ""))
117
+
118
+ def set_initial_schema(self, schema: dict[str, Any]) -> None:
119
+ """Pre-populate the picker with an existing schema selection.
120
+
121
+ Args:
122
+ schema: Schema dict with at least 'id' and 'schema_name' keys
123
+ """
124
+ self.set_initial_selection(schema)
125
+
126
+ def set_initial_schema_by_id(
127
+ self, schema_id: str, name: str = "Selected Schema"
128
+ ) -> None:
129
+ """Pre-populate the picker with a schema by its ID.
130
+
131
+ Use this when you only have the schema ID and not the full schema data.
132
+
133
+ Args:
134
+ schema_id: The schema UUID
135
+ name: Display name for the schema
136
+ """
137
+ self.set_initial_selection({"id": schema_id, "schema_name": name})
@@ -0,0 +1,103 @@
1
+ """Tag management modal for adding/removing tags from content.
2
+
3
+ Provides a modal screen that allows users to manage tags on a content part,
4
+ with the ability to search for tags and toggle their selection.
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ from textual import on
10
+ from textual.app import ComposeResult
11
+ from textual.binding import Binding
12
+ from textual.containers import Horizontal, Vertical
13
+ from textual.screen import ModalScreen
14
+ from textual.widgets import Button, Label, Static
15
+
16
+ from alloy_runtime_sdk.api_client.client import ApiClient
17
+
18
+ from cli.infrastructure.forms.tag_picker import TagPicker
19
+
20
+
21
+ class TagManagementModal(ModalScreen[list[str] | None]):
22
+ """Modal for managing tags on a content part.
23
+
24
+ Allows users to search for and select multiple tags. Returns the
25
+ updated list of tag paths on save, or None if cancelled.
26
+
27
+ Usage:
28
+ def on_tags_saved(result: list[str] | None):
29
+ if result is not None:
30
+ # result is the list of tag paths to set
31
+ pass
32
+
33
+ self.push_screen(
34
+ TagManagementModal(
35
+ client=server_client,
36
+ content_part_id="uuid-here",
37
+ current_tags=[{"tag_path": "existing.tag", ...}],
38
+ ),
39
+ on_tags_saved
40
+ )
41
+ """
42
+
43
+ BINDINGS = [
44
+ Binding("escape", "cancel", "Cancel", show=True),
45
+ ]
46
+
47
+ def __init__(
48
+ self,
49
+ client: ApiClient,
50
+ content_part_id: str,
51
+ current_tags: list[dict[str, Any]],
52
+ **kwargs: Any,
53
+ ) -> None:
54
+ """Initialize the tag management modal.
55
+
56
+ Args:
57
+ client: ApiClient instance for API calls
58
+ content_part_id: ID of the content part being edited
59
+ current_tags: Current tags on the content part
60
+ """
61
+ super().__init__(**kwargs)
62
+ self._client = client
63
+ self._content_part_id = content_part_id
64
+ self._current_tags = current_tags
65
+
66
+ def compose(self) -> ComposeResult:
67
+ # Format content ID for display (truncated)
68
+ display_id = self._content_part_id[:8] + "..."
69
+
70
+ with Vertical():
71
+ yield Label("Manage Tags", classes="modal-title")
72
+ yield Static(f"Content: {display_id}", classes="content-info")
73
+ yield Static("Search and select tags:", classes="section-label")
74
+ yield TagPicker(
75
+ client=self._client,
76
+ placeholder="Search for tags...",
77
+ empty_message="No tags selected",
78
+ id="tag-picker",
79
+ )
80
+ with Horizontal(classes="button-row"):
81
+ yield Button("Save", id="save-btn", variant="success")
82
+ yield Button("Cancel", id="cancel-btn", variant="default")
83
+
84
+ def on_mount(self) -> None:
85
+ """Pre-populate with current tags."""
86
+ picker = self.query_one("#tag-picker", TagPicker)
87
+ if self._current_tags:
88
+ picker.set_initial_selection(self._current_tags)
89
+
90
+ @on(Button.Pressed, "#save-btn")
91
+ def on_save_pressed(self, event: Button.Pressed) -> None:
92
+ """Save and dismiss with selected tags."""
93
+ picker = self.query_one("#tag-picker", TagPicker)
94
+ self.dismiss(picker.selected_tags)
95
+
96
+ @on(Button.Pressed, "#cancel-btn")
97
+ def on_cancel_pressed(self, event: Button.Pressed) -> None:
98
+ """Cancel and dismiss with None."""
99
+ self.dismiss(None)
100
+
101
+ def action_cancel(self) -> None:
102
+ """Cancel via escape key."""
103
+ self.dismiss(None)