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,522 @@
1
+ """Schemas screen for browsing and managing validation schemas.
2
+
3
+ This screen provides:
4
+ - Search and browse input/output schemas
5
+ - View schema definitions in preview panel
6
+ - Edit schema definitions in $EDITOR
7
+ - Create new schema versions
8
+ - Copy schema names and definitions
9
+ """
10
+
11
+ import json
12
+ import os
13
+ import subprocess
14
+ import tempfile
15
+ from typing import TYPE_CHECKING, Any
16
+ from uuid import UUID
17
+
18
+ from textual import on, work
19
+ from textual.app import ComposeResult
20
+ from textual.binding import Binding
21
+ from textual.widgets import DataTable, Static
22
+
23
+ from alloy_runtime_types.dtos.schemas import (
24
+ GetSchemaResponse,
25
+ SchemaSummary,
26
+ UpdateSchemaRequest,
27
+ )
28
+
29
+ from cli.infrastructure.scope_utils import format_scope_label
30
+ from cli.infrastructure.tui.clipboard import copy_to_clipboard
31
+ from cli.infrastructure.tui.formatters import format_datetime, truncate_text
32
+ from cli.tui.screens.base import BrowserWidget
33
+ from cli.tui.screens.nav_screen import NavScreen
34
+ from cli.tui.widgets.schema_create_modal import SchemaCreateModal, SchemaCreateResult
35
+ from cli.tui.widgets.schema_update_modal import SchemaUpdateModal, SchemaUpdateResult
36
+
37
+ if TYPE_CHECKING:
38
+ from cli.tui.app import AlloyRuntimeApp
39
+
40
+
41
+ class SchemasWidget(BrowserWidget[SchemaSummary]):
42
+ """Widget for browsing and managing schemas."""
43
+
44
+ app: "AlloyRuntimeApp"
45
+
46
+ TITLE = "Schemas"
47
+ TABLE_COLUMNS = ["Name", "Format", "Version", "Updated"]
48
+
49
+ def __init__(self, **kwargs: Any) -> None:
50
+ super().__init__(**kwargs)
51
+ # Cache for full schema details (keyed by schema ID)
52
+ self._schema_cache: dict[str, GetSchemaResponse] = {}
53
+
54
+ async def _fetch_items(self, query: str) -> tuple[list[SchemaSummary], int]:
55
+ """Fetch schemas from the API."""
56
+ client = await self._ensure_client()
57
+ response = await client.list_schemas(
58
+ search=query if query else None,
59
+ limit=50,
60
+ )
61
+ return response.schemas, response.total
62
+
63
+ def _format_row(self, item: SchemaSummary) -> tuple[str, ...]:
64
+ """Format a schema as a table row."""
65
+ return (
66
+ truncate_text(item.schema_name, max_length=40),
67
+ item.schema_format_id,
68
+ f"v{item.version}" if item.is_latest else f"v{item.version} (old)",
69
+ format_datetime(item.updated_at),
70
+ )
71
+
72
+ @on(DataTable.RowHighlighted)
73
+ def _on_row_highlighted(self, event: DataTable.RowHighlighted) -> None:
74
+ """Fetch full schema details when row is highlighted."""
75
+ row_index = event.cursor_row
76
+ if 0 <= row_index < len(self._items):
77
+ schema_summary = self._items[row_index]
78
+ schema_id = str(schema_summary.id)
79
+
80
+ # Check cache first
81
+ if schema_id in self._schema_cache:
82
+ self._update_preview_with_full_schema(
83
+ schema_summary, self._schema_cache[schema_id]
84
+ )
85
+ else:
86
+ # Fetch full details and update preview
87
+ self._fetch_full_schema(schema_summary)
88
+
89
+ @work(exclusive=True, group="schema_fetch")
90
+ async def _fetch_full_schema(self, schema_summary: SchemaSummary) -> None:
91
+ """Fetch full schema details from API and update preview."""
92
+ try:
93
+ client = await self._ensure_client()
94
+ full_schema = await client.get_schema(str(schema_summary.id))
95
+
96
+ # Cache the result
97
+ self._schema_cache[str(schema_summary.id)] = full_schema
98
+
99
+ # Update preview with full details
100
+ self._update_preview_with_full_schema(schema_summary, full_schema)
101
+
102
+ except Exception as e:
103
+ # Fall back to summary-only preview
104
+ self._update_preview(schema_summary)
105
+ self.app.notify(f"Failed to fetch schema details: {e}", severity="warning")
106
+
107
+ def _update_preview(self, item: SchemaSummary) -> None:
108
+ """Update the preview pane with schema summary (fallback)."""
109
+ preview = self.query_one("#preview-content", Static)
110
+
111
+ created = format_datetime(item.created_at)
112
+ scope = format_scope_label(
113
+ str(item.organization_id) if item.organization_id else None,
114
+ str(item.user_id) if item.user_id else None,
115
+ )
116
+
117
+ preview_text = f"""[bold]Schema ID:[/] {item.id}
118
+ [bold]Name:[/] {item.schema_name}
119
+ [bold]Format:[/] {item.schema_format_id}
120
+ [bold]Version:[/] v{item.version} {"(latest)" if item.is_latest else "(superseded)"}
121
+ [bold]Scope:[/] {scope}
122
+
123
+ [bold]Description:[/]
124
+ {item.description or "(no description)"}
125
+
126
+ [bold]Created:[/] {created}
127
+
128
+ [italic]Loading schema definition...[/]"""
129
+
130
+ preview.update(preview_text)
131
+
132
+ def _update_preview_with_full_schema(
133
+ self, summary: SchemaSummary, full_schema: GetSchemaResponse
134
+ ) -> None:
135
+ """Update the preview pane with full schema details including definition."""
136
+ preview = self.query_one("#preview-content", Static)
137
+
138
+ created = format_datetime(summary.created_at)
139
+ scope = format_scope_label(
140
+ str(summary.organization_id) if summary.organization_id else None,
141
+ str(summary.user_id) if summary.user_id else None,
142
+ )
143
+
144
+ # Format the schema definition for display
145
+ definition_display = self._format_definition_for_display(
146
+ full_schema.schema_definition, full_schema.schema_format_id
147
+ )
148
+
149
+ preview_text = f"""[bold]Schema ID:[/] {summary.id}
150
+ [bold]Name:[/] {summary.schema_name}
151
+ [bold]Format:[/] {summary.schema_format_id}
152
+ [bold]Version:[/] v{summary.version} {"(latest)" if summary.is_latest else "(superseded)"}
153
+ [bold]Scope:[/] {scope}
154
+
155
+ [bold]Description:[/]
156
+ {summary.description or "(no description)"}
157
+
158
+ [bold]Created:[/] {created}
159
+
160
+ [bold]Definition:[/]
161
+ {definition_display}"""
162
+
163
+ preview.update(preview_text)
164
+
165
+ def _format_definition_for_display(
166
+ self, definition: str, schema_format: str
167
+ ) -> str:
168
+ """Format schema definition for preview display."""
169
+ if schema_format == "json_schema":
170
+ try:
171
+ parsed = json.loads(definition)
172
+ formatted = json.dumps(parsed, indent=2, ensure_ascii=False)
173
+ # Truncate if too long
174
+ max_length = 2000
175
+ if len(formatted) > max_length:
176
+ formatted = formatted[:max_length] + "\n... (truncated)"
177
+ return formatted
178
+ except (json.JSONDecodeError, TypeError):
179
+ return definition
180
+ else:
181
+ # Regex or other formats - display as-is
182
+ return definition
183
+
184
+ def _get_cached_schema(self, schema_id: str) -> GetSchemaResponse | None:
185
+ """Get cached full schema details, or None if not cached."""
186
+ return self._schema_cache.get(schema_id)
187
+
188
+ def _open_editor_for_schema(
189
+ self, name_hint: str, initial_content: str, schema_format: str
190
+ ) -> str | None:
191
+ """Open external editor with schema definition.
192
+
193
+ Args:
194
+ name_hint: Name to include in temp file name
195
+ initial_content: Initial schema definition content
196
+ schema_format: Schema format (json_schema or regex)
197
+
198
+ Returns:
199
+ Edited content, or None if editor failed
200
+ """
201
+ editor = os.environ.get("EDITOR") or os.environ.get("VISUAL") or "vi"
202
+
203
+ # Choose file extension based on schema format for syntax highlighting
204
+ if schema_format == "json_schema":
205
+ suffix = ".json"
206
+ # Pretty-print JSON for better editing experience
207
+ try:
208
+ parsed = json.loads(initial_content)
209
+ initial_content = json.dumps(parsed, indent=2, ensure_ascii=False)
210
+ except (json.JSONDecodeError, TypeError):
211
+ pass
212
+ else:
213
+ suffix = ".txt"
214
+
215
+ try:
216
+ with tempfile.NamedTemporaryFile(
217
+ mode="w",
218
+ suffix=suffix,
219
+ prefix=f"schema_{name_hint}_",
220
+ delete=False,
221
+ encoding="utf-8",
222
+ ) as f:
223
+ f.write(initial_content)
224
+ temp_path = f.name
225
+
226
+ with self.app.suspend():
227
+ subprocess.run([editor, temp_path], check=False)
228
+
229
+ with open(temp_path, encoding="utf-8") as f:
230
+ new_content = f.read()
231
+
232
+ try:
233
+ os.unlink(temp_path)
234
+ except OSError:
235
+ pass
236
+
237
+ return new_content
238
+
239
+ except Exception as e:
240
+ self.app.notify(f"Failed to open editor: {e}", severity="error")
241
+ return None
242
+
243
+ # =========================================================================
244
+ # Public methods for parent Screen to call
245
+ # =========================================================================
246
+
247
+ def copy_schema_name(self) -> None:
248
+ """Copy the schema name to clipboard."""
249
+ schema = self.get_selected_item()
250
+ if not schema:
251
+ self.app.notify("No schema selected", severity="warning")
252
+ return
253
+
254
+ copy_to_clipboard(self.app, schema.schema_name, "Schema name")
255
+
256
+ async def open_new_schema_modal(self) -> None:
257
+ """Open the schema creation form."""
258
+ client = await self._ensure_client()
259
+
260
+ def on_schema_created(result: SchemaCreateResult | None) -> None:
261
+ if result is not None:
262
+ self.app.notify(
263
+ f"Created schema: {result.schema_name} v{result.version}",
264
+ severity="information",
265
+ )
266
+ self.refresh_data()
267
+
268
+ self.app.push_screen(
269
+ SchemaCreateModal(client=client),
270
+ on_schema_created,
271
+ )
272
+
273
+ def copy_schema_definition(self) -> None:
274
+ """Copy the schema definition to clipboard."""
275
+ schema = self.get_selected_item()
276
+ if not schema:
277
+ self.app.notify("No schema selected", severity="warning")
278
+ return
279
+
280
+ # Get full schema from cache
281
+ full_schema = self._get_cached_schema(str(schema.id))
282
+ if not full_schema:
283
+ self.app.notify(
284
+ "Schema definition not loaded yet. Please wait.", severity="warning"
285
+ )
286
+ return
287
+
288
+ # Format JSON nicely for clipboard
289
+ definition = full_schema.schema_definition
290
+ if full_schema.schema_format_id == "json_schema":
291
+ try:
292
+ parsed = json.loads(definition)
293
+ definition = json.dumps(parsed, indent=2, ensure_ascii=False)
294
+ except (json.JSONDecodeError, TypeError):
295
+ pass
296
+
297
+ copy_to_clipboard(self.app, definition, "Schema definition")
298
+
299
+ def edit_schema_definition(self) -> None:
300
+ """Open schema definition in $EDITOR for editing.
301
+
302
+ If the definition changes, creates a new version of the schema.
303
+ """
304
+ schema = self.get_selected_item()
305
+ if not schema:
306
+ self.app.notify("No schema selected", severity="warning")
307
+ return
308
+
309
+ # Get full schema from cache
310
+ full_schema = self._get_cached_schema(str(schema.id))
311
+ if not full_schema:
312
+ self.app.notify(
313
+ "Schema definition not loaded yet. Please wait.", severity="warning"
314
+ )
315
+ return
316
+
317
+ # Open in editor
318
+ new_content = self._open_editor_for_schema(
319
+ name_hint=schema.schema_name,
320
+ initial_content=full_schema.schema_definition,
321
+ schema_format=full_schema.schema_format_id,
322
+ )
323
+
324
+ if new_content is None:
325
+ return
326
+
327
+ # Normalize for comparison (strip whitespace, compact JSON)
328
+ original = full_schema.schema_definition.strip()
329
+ edited = new_content.strip()
330
+
331
+ # For JSON schemas, compare parsed content to ignore formatting differences
332
+ if full_schema.schema_format_id == "json_schema":
333
+ try:
334
+ original_parsed = json.loads(original)
335
+ edited_parsed = json.loads(edited)
336
+ if original_parsed == edited_parsed:
337
+ self.app.notify("No changes made", severity="information")
338
+ return
339
+ except json.JSONDecodeError:
340
+ # Fall back to string comparison
341
+ if original == edited:
342
+ self.app.notify("No changes made", severity="information")
343
+ return
344
+ else:
345
+ if original == edited:
346
+ self.app.notify("No changes made", severity="information")
347
+ return
348
+
349
+ # Save the updated schema (creates new version)
350
+ self._save_schema_update(str(schema.id), edited)
351
+
352
+ def create_schema_version(self) -> None:
353
+ """Create a new version of the schema in $EDITOR.
354
+
355
+ Opens the current definition in editor. If content changes,
356
+ creates a new version.
357
+ """
358
+ # Same as edit - both create new versions on change
359
+ self.edit_schema_definition()
360
+
361
+ @work(exclusive=True)
362
+ async def _save_schema_update(self, schema_id: str, new_definition: str) -> None:
363
+ """Save updated schema definition via API (creates new version)."""
364
+ try:
365
+ client = await self._ensure_client()
366
+ request = UpdateSchemaRequest(schema_definition=new_definition)
367
+ response = await client.update_schema(UUID(schema_id), request)
368
+
369
+ # Clear cache for this schema (new version has new ID)
370
+ if schema_id in self._schema_cache:
371
+ del self._schema_cache[schema_id]
372
+
373
+ self.app.notify(
374
+ f"Schema updated: {response.schema_name} v{response.version}",
375
+ severity="information",
376
+ )
377
+
378
+ # Refresh the list to show new version
379
+ self._do_search(self._last_search)
380
+
381
+ except Exception as e:
382
+ self.app.notify(f"Failed to update schema: {e}", severity="error")
383
+
384
+ def open_edit_schema_modal(self) -> None:
385
+ """Open the schema update modal to edit name/description."""
386
+ schema = self.get_selected_item()
387
+ if not schema:
388
+ self.app.notify("No schema selected", severity="warning")
389
+ return
390
+
391
+ # Get full schema from cache
392
+ full_schema = self._get_cached_schema(str(schema.id))
393
+ if not full_schema:
394
+ self.app.notify(
395
+ "Schema details not loaded yet. Please wait.", severity="warning"
396
+ )
397
+ return
398
+
399
+ self._open_schema_update_modal(full_schema)
400
+
401
+ @work(exclusive=True)
402
+ async def _open_schema_update_modal(self, schema: GetSchemaResponse) -> None:
403
+ """Open the schema update modal."""
404
+ try:
405
+ client = await self._ensure_client()
406
+ self.app.push_screen(
407
+ SchemaUpdateModal(client=client, schema=schema),
408
+ self._on_schema_updated,
409
+ )
410
+ except Exception as e:
411
+ self.app.notify(f"Failed to open schema editor: {e}", severity="error")
412
+
413
+ def _on_schema_updated(self, result: SchemaUpdateResult | None) -> None:
414
+ """Callback when schema update modal is dismissed."""
415
+ if result is not None:
416
+ # Clear cache for this schema (name may have changed)
417
+ if result.schema_id in self._schema_cache:
418
+ del self._schema_cache[result.schema_id]
419
+
420
+ self.app.notify(
421
+ f"Updated schema: {result.schema_name}",
422
+ severity="information",
423
+ )
424
+ # Refresh the schema list
425
+ self._do_search(self._last_search)
426
+
427
+
428
+ class SchemasScreen(NavScreen):
429
+ """Screen for browsing and managing schemas.
430
+
431
+ This is a proper Textual Screen that wraps the SchemasWidget
432
+ and provides keybindings that work regardless of focus.
433
+ """
434
+
435
+ app: "AlloyRuntimeApp"
436
+
437
+ SCREEN_ID = "schemas"
438
+
439
+ DEFAULT_CSS = """
440
+ SchemasScreen #screen-root {
441
+ height: 1fr;
442
+ }
443
+
444
+ SchemasScreen .browser-widget {
445
+ height: 100%;
446
+ width: 100%;
447
+ }
448
+ """
449
+
450
+ # Screen-specific bindings (Ctrl+ prefixed)
451
+ BINDINGS = NavScreen.BINDINGS + [
452
+ Binding("ctrl+f", "focus_search", "Search", show=True),
453
+ Binding("ctrl+r", "refresh", "Refresh", show=True),
454
+ Binding("ctrl+y", "copy_name", "Copy Name", show=True),
455
+ Binding("ctrl+shift+y", "copy_definition", "Copy Definition", show=True),
456
+ Binding("ctrl+e", "edit_definition", "Edit Def", show=True),
457
+ Binding("ctrl+u", "edit_schema", "Edit Name", show=True),
458
+ Binding("ctrl+v", "create_version", "New Version", show=True),
459
+ Binding("ctrl+n", "new_schema", "New", show=True),
460
+ Binding("escape", "focus_table", "Focus List", show=False),
461
+ Binding("enter", "copy_name", "Copy Name", show=False),
462
+ ]
463
+
464
+ def compose_content(self) -> ComposeResult:
465
+ """Compose the screen content."""
466
+ yield SchemasWidget(id="schemas-widget")
467
+
468
+ def on_screen_resume(self) -> None:
469
+ """Focus the data table when screen becomes active."""
470
+ self.call_after_refresh(self._focus_table)
471
+
472
+ def _focus_table(self) -> None:
473
+ """Focus the data table."""
474
+ try:
475
+ widget = self.query_one("#schemas-widget", SchemasWidget)
476
+ widget.focus_table()
477
+ except Exception:
478
+ pass
479
+
480
+ def _get_widget(self) -> SchemasWidget:
481
+ """Get the schemas widget."""
482
+ return self.query_one("#schemas-widget", SchemasWidget)
483
+
484
+ # =========================================================================
485
+ # Actions (keybinding handlers)
486
+ # =========================================================================
487
+
488
+ def action_focus_search(self) -> None:
489
+ """Focus the search input."""
490
+ self._get_widget().focus_search()
491
+
492
+ def action_focus_table(self) -> None:
493
+ """Focus the data table."""
494
+ self._get_widget().focus_table()
495
+
496
+ def action_refresh(self) -> None:
497
+ """Refresh the current search results."""
498
+ self._get_widget().refresh_data()
499
+
500
+ def action_copy_name(self) -> None:
501
+ """Copy the schema name to clipboard."""
502
+ self._get_widget().copy_schema_name()
503
+
504
+ def action_copy_definition(self) -> None:
505
+ """Copy the schema definition to clipboard."""
506
+ self._get_widget().copy_schema_definition()
507
+
508
+ def action_edit_definition(self) -> None:
509
+ """Edit the schema definition in $EDITOR."""
510
+ self._get_widget().edit_schema_definition()
511
+
512
+ def action_edit_schema(self) -> None:
513
+ """Edit the schema name and description in a modal."""
514
+ self._get_widget().open_edit_schema_modal()
515
+
516
+ def action_create_version(self) -> None:
517
+ """Create a new version of the schema."""
518
+ self._get_widget().create_schema_version()
519
+
520
+ async def action_new_schema(self) -> None:
521
+ """Open the schema creation modal."""
522
+ await self._get_widget().open_new_schema_modal()