acra-cli 0.1.2__tar.gz → 0.1.3__tar.gz

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 (182) hide show
  1. {acra_cli-0.1.2/acra_cli.egg-info → acra_cli-0.1.3}/PKG-INFO +1 -1
  2. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/cli.py +33 -3
  3. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/__init__.py +2 -0
  4. acra_cli-0.1.3/acra/commands/ask.py +95 -0
  5. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/research.py +6 -2
  6. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/ui/__pycache__/banner.cpython-312.pyc +0 -0
  7. {acra_cli-0.1.2 → acra_cli-0.1.3/acra_cli.egg-info}/PKG-INFO +1 -1
  8. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra_cli.egg-info/SOURCES.txt +2 -1
  9. {acra_cli-0.1.2 → acra_cli-0.1.3}/pyproject.toml +1 -1
  10. acra_cli-0.1.3/tests/test_cli.py +91 -0
  11. acra_cli-0.1.3/tests/test_interactive_routing.py +53 -0
  12. acra_cli-0.1.2/acra/commands/ask.py +0 -49
  13. acra_cli-0.1.2/tests/test_cli.py +0 -36
  14. {acra_cli-0.1.2 → acra_cli-0.1.3}/LICENSE +0 -0
  15. {acra_cli-0.1.2 → acra_cli-0.1.3}/MANIFEST.in +0 -0
  16. {acra_cli-0.1.2 → acra_cli-0.1.3}/README.md +0 -0
  17. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/__init__.py +0 -0
  18. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/__main__.py +0 -0
  19. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/__init__.py +0 -0
  20. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/__pycache__/__init__.cpython-312.pyc +0 -0
  21. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/__pycache__/llm.cpython-312.pyc +0 -0
  22. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/__pycache__/llm_utils.cpython-312.pyc +0 -0
  23. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/coder/__init__.py +0 -0
  24. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/coder/__pycache__/__init__.cpython-312.pyc +0 -0
  25. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/coder/__pycache__/coder_agent.cpython-312.pyc +0 -0
  26. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/coder/__pycache__/coder_chain.cpython-312.pyc +0 -0
  27. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/coder/coder_agent.py +0 -0
  28. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/coder/coder_chain.py +0 -0
  29. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/critic/__init__.py +0 -0
  30. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/critic/__pycache__/__init__.cpython-312.pyc +0 -0
  31. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/critic/__pycache__/critic_agent.cpython-312.pyc +0 -0
  32. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/critic/__pycache__/critic_chain.cpython-312.pyc +0 -0
  33. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/critic/critic_agent.py +0 -0
  34. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/critic/critic_chain.py +0 -0
  35. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/executor/__init__.py +0 -0
  36. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/executor/__pycache__/__init__.cpython-312.pyc +0 -0
  37. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/executor/__pycache__/docker_runner.cpython-312.pyc +0 -0
  38. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/executor/__pycache__/executor_agent.cpython-312.pyc +0 -0
  39. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/executor/__pycache__/sandbox_runner.cpython-312.pyc +0 -0
  40. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/executor/docker_runner.py +0 -0
  41. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/executor/executor_agent.py +0 -0
  42. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/executor/sandbox_runner.py +0 -0
  43. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/human/__init__.py +0 -0
  44. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/human/__pycache__/__init__.cpython-312.pyc +0 -0
  45. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/human/__pycache__/human_node.cpython-312.pyc +0 -0
  46. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/human/human_node.py +0 -0
  47. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/llm.py +0 -0
  48. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/llm_utils.py +0 -0
  49. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/memory/__init__.py +0 -0
  50. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/memory/__pycache__/__init__.cpython-312.pyc +0 -0
  51. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/memory/__pycache__/memory_agent.cpython-312.pyc +0 -0
  52. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/memory/__pycache__/memory_manager.cpython-312.pyc +0 -0
  53. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/memory/__pycache__/retrieval.cpython-312.pyc +0 -0
  54. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/memory/memory_agent.py +0 -0
  55. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/memory/memory_manager.py +0 -0
  56. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/memory/retrieval.py +0 -0
  57. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/planner/__init__.py +0 -0
  58. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/planner/__pycache__/__init__.cpython-312.pyc +0 -0
  59. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/planner/__pycache__/planner_agent.cpython-312.pyc +0 -0
  60. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/planner/__pycache__/planner_chain.cpython-312.pyc +0 -0
  61. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/planner/planner_agent.py +0 -0
  62. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/planner/planner_chain.py +0 -0
  63. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/researcher/__init__.py +0 -0
  64. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/researcher/__pycache__/__init__.cpython-312.pyc +0 -0
  65. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/researcher/__pycache__/researcher_agent.cpython-312.pyc +0 -0
  66. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/researcher/__pycache__/researcher_chain.cpython-312.pyc +0 -0
  67. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/researcher/researcher_agent.py +0 -0
  68. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/agents/researcher/researcher_chain.py +0 -0
  69. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/brain/__init__.py +0 -0
  70. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/brain/model_registry.py +0 -0
  71. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/brain/provider_manager.py +0 -0
  72. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/brain.py +0 -0
  73. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/config.py +0 -0
  74. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/context.py +0 -0
  75. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/graph.py +0 -0
  76. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/keys.py +0 -0
  77. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/logs.py +0 -0
  78. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/memory.py +0 -0
  79. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/plugin.py +0 -0
  80. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/serve.py +0 -0
  81. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/session.py +0 -0
  82. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/commands/utils.py +0 -0
  83. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/config/__init__.py +0 -0
  84. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/config/__pycache__/__init__.cpython-312.pyc +0 -0
  85. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/config/__pycache__/defaults.cpython-312.pyc +0 -0
  86. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/config/__pycache__/profile_manager.cpython-312.pyc +0 -0
  87. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/config/defaults.py +0 -0
  88. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/config/profile_manager.py +0 -0
  89. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/execution/__init__.py +0 -0
  90. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/execution/logs/__init__.py +0 -0
  91. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/execution/logs/error_logs/__init__.py +0 -0
  92. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/execution/logs/execution_logs/__init__.py +0 -0
  93. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/execution/sandbox/__init__.py +0 -0
  94. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/execution/sandbox/docker_executor.py +0 -0
  95. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/execution/sandbox/isolated_runner.py +0 -0
  96. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/execution/sandbox/sandbox_manager.py +0 -0
  97. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/graph/__init__.py +0 -0
  98. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/graph/checkpoint.py +0 -0
  99. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/graph/conditional_edges.py +0 -0
  100. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/graph/edges.py +0 -0
  101. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/graph/graph_visualizer.py +0 -0
  102. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/graph/nodes.py +0 -0
  103. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/graph/router.py +0 -0
  104. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/graph/state.py +0 -0
  105. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/graph/workflow.py +0 -0
  106. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/__init__.py +0 -0
  107. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/checkpoints/__init__.py +0 -0
  108. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/checkpoints/data/__init__.py +0 -0
  109. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/checkpoints/postgres_checkpoint.py +0 -0
  110. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/checkpoints/sqlite_checkpoint.py +0 -0
  111. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/chroma_db/__init__.py +0 -0
  112. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/conversation_memory/__init__.py +0 -0
  113. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/conversation_memory/long_term.py +0 -0
  114. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/conversation_memory/short_term.py +0 -0
  115. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/storage/__init__.py +0 -0
  116. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/vector_store/__init__.py +0 -0
  117. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/vector_store/chroma_store.py +0 -0
  118. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/memory/vector_store/embeddings.py +0 -0
  119. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/observability/__init__.py +0 -0
  120. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/observability/langsmith_tracing.py +0 -0
  121. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/observability/metrics.py +0 -0
  122. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/observability/monitoring.py +0 -0
  123. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/observability/token_tracking.py +0 -0
  124. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/prompts/__init__.py +0 -0
  125. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/__init__.py +0 -0
  126. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/__pycache__/__init__.cpython-312.pyc +0 -0
  127. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/__pycache__/coder_schema.cpython-312.pyc +0 -0
  128. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/__pycache__/critic_schema.cpython-312.pyc +0 -0
  129. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/__pycache__/execution_schema.cpython-312.pyc +0 -0
  130. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/__pycache__/planner_schema.cpython-312.pyc +0 -0
  131. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/__pycache__/researcher_schema.cpython-312.pyc +0 -0
  132. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/__pycache__/shared_schema.cpython-312.pyc +0 -0
  133. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/coder_schema.py +0 -0
  134. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/critic_schema.py +0 -0
  135. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/execution_schema.py +0 -0
  136. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/planner_schema.py +0 -0
  137. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/researcher_schema.py +0 -0
  138. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/schemas/shared_schema.py +0 -0
  139. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/__init__.py +0 -0
  140. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/code_tools/__init__.py +0 -0
  141. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/code_tools/file_reader.py +0 -0
  142. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/code_tools/file_writer.py +0 -0
  143. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/code_tools/python_repl.py +0 -0
  144. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/code_tools/terminal_runner.py +0 -0
  145. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/github_tools/__init__.py +0 -0
  146. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/github_tools/commit_generator.py +0 -0
  147. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/github_tools/github_search.py +0 -0
  148. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/github_tools/repo_analyzer.py +0 -0
  149. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/integration_test_helper.py +0 -0
  150. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/validation_tools/__init__.py +0 -0
  151. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/validation_tools/dependency_checker.py +0 -0
  152. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/validation_tools/environment_config_validator.py +0 -0
  153. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/validation_tools/http_validator.py +0 -0
  154. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/validation_tools/response_validator.py +0 -0
  155. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/validation_tools/security_checker.py +0 -0
  156. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/validation_tools/syntax_checker.py +0 -0
  157. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/validation_tools/web_framework_validator.py +0 -0
  158. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/web_tools/__init__.py +0 -0
  159. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/web_tools/arxiv_search.py +0 -0
  160. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/web_tools/serpapi_search.py +0 -0
  161. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/tools/web_tools/tavily_search.py +0 -0
  162. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/ui/__init__.py +0 -0
  163. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/ui/__pycache__/__init__.cpython-312.pyc +0 -0
  164. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/ui/__pycache__/components.cpython-312.pyc +0 -0
  165. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/ui/__pycache__/shell.cpython-312.pyc +0 -0
  166. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/ui/__pycache__/theme.cpython-312.pyc +0 -0
  167. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/ui/banner.py +0 -0
  168. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/ui/components.py +0 -0
  169. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/ui/shell.py +0 -0
  170. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/ui/theme.py +0 -0
  171. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/utils/__init__.py +0 -0
  172. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/utils/context_manager.py +0 -0
  173. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/utils/keyring_manager.py +0 -0
  174. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/utils/output_formatter.py +0 -0
  175. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra/utils/session_manager.py +0 -0
  176. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra_cli.egg-info/dependency_links.txt +0 -0
  177. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra_cli.egg-info/entry_points.txt +0 -0
  178. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra_cli.egg-info/requires.txt +0 -0
  179. {acra_cli-0.1.2 → acra_cli-0.1.3}/acra_cli.egg-info/top_level.txt +0 -0
  180. {acra_cli-0.1.2 → acra_cli-0.1.3}/requirements.txt +0 -0
  181. {acra_cli-0.1.2 → acra_cli-0.1.3}/setup.cfg +0 -0
  182. {acra_cli-0.1.2 → acra_cli-0.1.3}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: acra-cli
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Agentic CLI for LLM task execution, research, and workflow automation.
5
5
  Author: Raj Tembe
6
6
  License: GNU Affero General Public License v3
@@ -2,11 +2,17 @@
2
2
 
3
3
  import typer
4
4
 
5
+ import acra
6
+ from acra.commands.ask import ask, build, explain, fix, review, run
7
+ from acra.commands.research import research
5
8
  from acra.commands import (
6
9
  serve_app,
7
10
  config_app,
8
11
  keys_app,
9
- research_app,
12
+ brain_app,
13
+ context_app,
14
+ logs_app,
15
+ plugin_app,
10
16
  memory_app,
11
17
  session_app,
12
18
  graph_app,
@@ -19,11 +25,28 @@ app = typer.Typer(add_completion=True)
19
25
  app.add_typer(serve_app, name="serve")
20
26
  app.add_typer(config_app, name="config")
21
27
  app.add_typer(keys_app, name="keys")
22
- app.add_typer(research_app, name="research")
23
28
  app.add_typer(memory_app, name="memory")
24
29
  app.add_typer(session_app, name="session")
25
30
  app.add_typer(graph_app, name="graph")
26
31
  app.add_typer(utils_app, name="workspace")
32
+ app.add_typer(brain_app, name="brain", help="Brain management commands for acra.")
33
+ app.add_typer(context_app, name="context", help="Context management commands for acra.")
34
+ app.add_typer(logs_app, name="logs", help="Logging commands for acra.")
35
+ app.add_typer(plugin_app, name="plugin", help="Plugin commands for acra.")
36
+
37
+ app.command("ask")(ask)
38
+ app.command("build")(build)
39
+ app.command("fix")(fix)
40
+ app.command("review")(review)
41
+ app.command("explain")(explain)
42
+ app.command("run")(run)
43
+ app.command("research")(research)
44
+
45
+
46
+ def _version_callback(value: bool):
47
+ if value:
48
+ typer.echo(acra.__version__)
49
+ raise typer.Exit()
27
50
 
28
51
 
29
52
  def app_main() -> None:
@@ -34,9 +57,16 @@ def app_main() -> None:
34
57
  @app.callback(invoke_without_command=True)
35
58
  def main(
36
59
  ctx: typer.Context,
60
+ version: bool = typer.Option(
61
+ False,
62
+ "--version",
63
+ callback=_version_callback,
64
+ is_eager=True,
65
+ help="Show the installed acra version and exit.",
66
+ ),
37
67
  profile: str = typer.Option(None, "--profile", help="Profile to use."),
38
68
  workspace: str = typer.Option(None, "--workspace", help="Override workspace path."),
39
- no_memory: bool = typer.Option(False, "--no-memory", help="Run without memory."),
69
+ use_memory: bool = typer.Option(True, "--memory/--no-memory", help="Use memory."),
40
70
  dry_run: bool = typer.Option(False, "--dry-run", help="Display planned actions without executing."),
41
71
  json_output: bool = typer.Option(False, "--json", help="Output JSON-formatted results."),
42
72
  verbose: bool = typer.Option(False, "--verbose", "-v", help="Enable verbose logging."),
@@ -1,6 +1,7 @@
1
1
  """acra command modules."""
2
2
 
3
3
  from .serve import app as serve_app
4
+ from .ask import app as ask_app
4
5
  from .config import app as config_app
5
6
  from .brain import app as brain_app
6
7
  from .research import app as research_app
@@ -15,6 +16,7 @@ from .utils import app as utils_app
15
16
 
16
17
  __all__ = [
17
18
  "serve_app",
19
+ "ask_app",
18
20
  "config_app",
19
21
  "brain_app",
20
22
  "research_app",
@@ -0,0 +1,95 @@
1
+ """Agent task commands for acra."""
2
+
3
+ from typing import Optional
4
+
5
+ import typer
6
+
7
+ from acra.graph.workflow import OmniAgentCallbacks, omniagent_graph
8
+ from acra.ui.components import render_panel
9
+
10
+ app = typer.Typer(help="Agent task commands for acra.")
11
+
12
+
13
+ def _run_task(
14
+ task: str,
15
+ task_label: str,
16
+ profile: Optional[str] = None,
17
+ use_memory: bool = True,
18
+ interactive: bool = False,
19
+ ):
20
+ state = {
21
+ "user_request": task,
22
+ "task_label": task_label,
23
+ "no_memory": not use_memory,
24
+ "profile": profile,
25
+ "interactive": interactive,
26
+ }
27
+ result = omniagent_graph.invoke(state, config={"callbacks": [OmniAgentCallbacks()]})
28
+ render_panel(result, title=task_label)
29
+ return result
30
+
31
+
32
+ @app.command()
33
+ def ask(
34
+ task: str = typer.Argument(..., help="Task or question for the agent."),
35
+ profile: Optional[str] = typer.Option(None, help="Profile to use."),
36
+ use_memory: bool = typer.Option(True, "--memory/--no-memory", help="Use memory for this task."),
37
+ interactive: bool = typer.Option(False, "--interactive", help="Route agent approval requests to the human node."),
38
+ ):
39
+ """Ask the assistant a question."""
40
+ return _run_task(task, "ask", profile, use_memory, interactive)
41
+
42
+
43
+ @app.command()
44
+ def build(
45
+ task: str = typer.Argument(..., help="Build task for the agent."),
46
+ profile: Optional[str] = typer.Option(None, help="Profile to use."),
47
+ use_memory: bool = typer.Option(True, "--memory/--no-memory", help="Use memory for this task."),
48
+ interactive: bool = typer.Option(False, "--interactive", help="Route agent approval requests to the human node."),
49
+ ):
50
+ """Run a build workflow for a project task."""
51
+ return _run_task(task, "build", profile, use_memory, interactive)
52
+
53
+
54
+ @app.command()
55
+ def fix(
56
+ task: str = typer.Argument(..., help="Code issue or bug for the agent to fix."),
57
+ profile: Optional[str] = typer.Option(None, help="Profile to use."),
58
+ use_memory: bool = typer.Option(True, "--memory/--no-memory", help="Use memory for this task."),
59
+ interactive: bool = typer.Option(False, "--interactive", help="Route agent approval requests to the human node."),
60
+ ):
61
+ """Run a fix workflow for a code issue."""
62
+ return _run_task(task, "fix", profile, use_memory, interactive)
63
+
64
+
65
+ @app.command()
66
+ def review(
67
+ task: str = typer.Argument(..., help="Code, design, or task to review."),
68
+ profile: Optional[str] = typer.Option(None, help="Profile to use."),
69
+ use_memory: bool = typer.Option(True, "--memory/--no-memory", help="Use memory for this task."),
70
+ interactive: bool = typer.Option(False, "--interactive", help="Route agent approval requests to the human node."),
71
+ ):
72
+ """Review code or design with the critic pipeline."""
73
+ return _run_task(task, "review", profile, use_memory, interactive)
74
+
75
+
76
+ @app.command()
77
+ def explain(
78
+ task: str = typer.Argument(..., help="Concept or code path to explain."),
79
+ profile: Optional[str] = typer.Option(None, help="Profile to use."),
80
+ use_memory: bool = typer.Option(True, "--memory/--no-memory", help="Use memory for this task."),
81
+ interactive: bool = typer.Option(False, "--interactive", help="Route agent approval requests to the human node."),
82
+ ):
83
+ """Explain a technical concept or code path."""
84
+ return _run_task(task, "explain", profile, use_memory, interactive)
85
+
86
+
87
+ @app.command()
88
+ def run(
89
+ task: str = typer.Argument(..., help="Task for the agent to execute."),
90
+ profile: Optional[str] = typer.Option(None, help="Profile to use."),
91
+ use_memory: bool = typer.Option(True, "--memory/--no-memory", help="Use memory for this task."),
92
+ interactive: bool = typer.Option(False, "--interactive", help="Route agent approval requests to the human node."),
93
+ ):
94
+ """Execute a task using the executor agent."""
95
+ return _run_task(task, "run", profile, use_memory, interactive)
@@ -27,7 +27,11 @@ def research(
27
27
  output: Optional[str] = typer.Option(None, help="Write research output to a file."),
28
28
  save: bool = typer.Option(False, help="Persist research output into memory."),
29
29
  follow_up: bool = typer.Option(False, help="Keep the session open for follow-up questions."),
30
- no_memory: bool = typer.Option(False, help="Skip memory persistence for this research."),
30
+ use_memory: bool = typer.Option(
31
+ True,
32
+ "--memory/--no-memory",
33
+ help="Use memory persistence for this research.",
34
+ ),
31
35
  profile: Optional[str] = typer.Option(None, help="Profile to use."),
32
36
  json_output: bool = typer.Option(False, "--json", help="Output JSON instead of rich text."),
33
37
  verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed debug output."),
@@ -45,7 +49,7 @@ def research(
45
49
  "research_depth": depth,
46
50
  "research_sources": source_list,
47
51
  "follow_up": follow_up,
48
- "save_to_memory": save and not no_memory,
52
+ "save_to_memory": save and use_memory,
49
53
  "profile": profile,
50
54
  }
51
55
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: acra-cli
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Agentic CLI for LLM task execution, research, and workflow automation.
5
5
  Author: Raj Tembe
6
6
  License: GNU Affero General Public License v3
@@ -174,4 +174,5 @@ acra_cli.egg-info/dependency_links.txt
174
174
  acra_cli.egg-info/entry_points.txt
175
175
  acra_cli.egg-info/requires.txt
176
176
  acra_cli.egg-info/top_level.txt
177
- tests/test_cli.py
177
+ tests/test_cli.py
178
+ tests/test_interactive_routing.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "acra-cli"
7
- version = "0.1.2"
7
+ version = "0.1.3"
8
8
  description = "Agentic CLI for LLM task execution, research, and workflow automation."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -0,0 +1,91 @@
1
+ from typer.testing import CliRunner
2
+
3
+ from acra.cli import app
4
+ import acra.commands.ask as ask_module
5
+ import acra.commands.serve as serve_module
6
+
7
+
8
+ def test_root_cli_exposes_ask_commands():
9
+ runner = CliRunner()
10
+
11
+ result = runner.invoke(app, ["build", "--help"])
12
+
13
+ assert result.exit_code == 0
14
+ assert "Run a build workflow for a project task." in result.output
15
+
16
+
17
+ def test_root_cli_exposes_brain_command():
18
+ runner = CliRunner()
19
+
20
+ result = runner.invoke(app, ["brain", "--help"])
21
+
22
+ assert result.exit_code == 0
23
+ assert "Brain management commands for acra." in result.output
24
+
25
+
26
+ def test_root_cli_exposes_context_command():
27
+ runner = CliRunner()
28
+
29
+ result = runner.invoke(app, ["context", "--help"])
30
+
31
+ assert result.exit_code == 0
32
+ assert "Context management commands for acra." in result.output
33
+
34
+
35
+ def test_root_cli_exposes_logs_command():
36
+ runner = CliRunner()
37
+
38
+ result = runner.invoke(app, ["logs", "--help"])
39
+
40
+ assert result.exit_code == 0
41
+ assert "Logging commands for acra." in result.output
42
+
43
+
44
+ def test_root_cli_exposes_plugin_command():
45
+ runner = CliRunner()
46
+
47
+ result = runner.invoke(app, ["plugin", "--help"])
48
+
49
+ assert result.exit_code == 0
50
+ assert "Plugin commands for acra." in result.output
51
+
52
+
53
+ def test_brain_models_command_renders_without_crashing():
54
+ runner = CliRunner()
55
+
56
+ result = runner.invoke(app, ["brain", "models"])
57
+
58
+ assert result.exit_code == 0
59
+ assert "Models for all providers" in result.output
60
+
61
+
62
+ def test_build_command_sets_interactive_and_memory_flags(monkeypatch):
63
+ runner = CliRunner()
64
+ captured = {}
65
+
66
+ class FakeGraph:
67
+ def invoke(self, state, config=None):
68
+ captured["state"] = state
69
+ return {"ok": True}
70
+
71
+ monkeypatch.setattr(ask_module, "omniagent_graph", FakeGraph())
72
+ result = runner.invoke(app, ["build", "create a hello world script", "--interactive", "--no-memory"])
73
+
74
+ assert result.exit_code == 0
75
+ assert captured["state"]["task_label"] == "build"
76
+ assert captured["state"]["interactive"] is True
77
+ assert captured["state"]["no_memory"] is True
78
+
79
+
80
+ def test_serve_command_launches_shell_without_subcommand(monkeypatch):
81
+ runner = CliRunner()
82
+ called = {"value": False}
83
+
84
+ def fake_launch_shell(*args, **kwargs):
85
+ called["value"] = True
86
+
87
+ monkeypatch.setattr(serve_module, "launch_shell", fake_launch_shell)
88
+ result = runner.invoke(app, ["serve"])
89
+
90
+ assert result.exit_code == 0
91
+ assert called["value"] is True
@@ -0,0 +1,53 @@
1
+ from types import SimpleNamespace
2
+
3
+ from acra.agents.planner import planner_agent as planner_module
4
+
5
+
6
+ def test_planner_routes_to_human_when_interactive_approval_required(monkeypatch):
7
+ class FakePlannerChain:
8
+ def invoke(self, inputs):
9
+ return SimpleNamespace(
10
+ tasks=["Confirm plan"],
11
+ current_step="Confirm plan",
12
+ workflow_status="planning",
13
+ next_agent="coder",
14
+ require_human_approval=True,
15
+ )
16
+
17
+ monkeypatch.setattr(
18
+ planner_module,
19
+ "create_planner_chain",
20
+ lambda: FakePlannerChain(),
21
+ )
22
+
23
+ result = planner_module.planner_agent({
24
+ "user_request": "build a script",
25
+ "interactive": True,
26
+ })
27
+
28
+ assert result["next_agent"] == "human"
29
+
30
+
31
+ def test_planner_skips_human_route_without_interactive_flag(monkeypatch):
32
+ class FakePlannerChain:
33
+ def invoke(self, inputs):
34
+ return SimpleNamespace(
35
+ tasks=["Write code"],
36
+ current_step="Write code",
37
+ workflow_status="planning",
38
+ next_agent="coder",
39
+ require_human_approval=True,
40
+ )
41
+
42
+ monkeypatch.setattr(
43
+ planner_module,
44
+ "create_planner_chain",
45
+ lambda: FakePlannerChain(),
46
+ )
47
+
48
+ result = planner_module.planner_agent({
49
+ "user_request": "build a script",
50
+ "interactive": False,
51
+ })
52
+
53
+ assert result["next_agent"] == "coder"
@@ -1,49 +0,0 @@
1
- """Agent task commands for acra."""
2
-
3
- import uuid
4
- from typing import Optional
5
-
6
- from acra.graph.workflow import OmniAgentCallbacks, omniagent_graph
7
- from acra.ui.components import render_panel
8
-
9
-
10
- def _run_task(task: str, task_label: str, profile: Optional[str] = None, no_memory: bool = False):
11
- state = {
12
- "user_request": task,
13
- "task_label": task_label,
14
- "no_memory": no_memory,
15
- "profile": profile,
16
- }
17
- result = omniagent_graph.invoke(state, config={"callbacks": [OmniAgentCallbacks()]})
18
- render_panel(result, title=task_label)
19
- return result
20
-
21
-
22
- def ask(task: str, profile: Optional[str] = None, no_memory: bool = False):
23
- """Ask the assistant a question."""
24
- return _run_task(task, "ask", profile, no_memory)
25
-
26
-
27
- def build(task: str, profile: Optional[str] = None, no_memory: bool = False):
28
- """Run a build workflow for a project task."""
29
- return _run_task(task, "build", profile, no_memory)
30
-
31
-
32
- def fix(task: str, profile: Optional[str] = None, no_memory: bool = False):
33
- """Run a fix workflow for a code issue."""
34
- return _run_task(task, "fix", profile, no_memory)
35
-
36
-
37
- def review(task: str, profile: Optional[str] = None, no_memory: bool = False):
38
- """Review code or design with the critic pipeline."""
39
- return _run_task(task, "review", profile, no_memory)
40
-
41
-
42
- def explain(task: str, profile: Optional[str] = None, no_memory: bool = False):
43
- """Explain a technical concept or code path."""
44
- return _run_task(task, "explain", profile, no_memory)
45
-
46
-
47
- def run(task: str, profile: Optional[str] = None, no_memory: bool = False):
48
- """Execute a task using the executor agent."""
49
- return _run_task(task, "run", profile, no_memory)
@@ -1,36 +0,0 @@
1
- from typer.testing import CliRunner
2
-
3
- from acra.cli import app
4
- import acra.commands.serve as serve_module
5
-
6
-
7
- def test_root_cli_exposes_brain_command():
8
- runner = CliRunner()
9
-
10
- result = runner.invoke(app, ["brain", "--help"])
11
-
12
- assert result.exit_code == 0
13
- assert "Brain management commands for acra." in result.output
14
-
15
-
16
- def test_brain_models_command_renders_without_crashing():
17
- runner = CliRunner()
18
-
19
- result = runner.invoke(app, ["brain", "models"])
20
-
21
- assert result.exit_code == 0
22
- assert "Models for all providers" in result.output
23
-
24
-
25
- def test_serve_command_launches_shell_without_subcommand(monkeypatch):
26
- runner = CliRunner()
27
- called = {"value": False}
28
-
29
- def fake_launch_shell(*args, **kwargs):
30
- called["value"] = True
31
-
32
- monkeypatch.setattr(serve_module, "launch_shell", fake_launch_shell)
33
- result = runner.invoke(app, ["serve"])
34
-
35
- assert result.exit_code == 0
36
- assert called["value"] is True
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes