alita-sdk 0.3.462__py3-none-any.whl → 0.3.627__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 (261) hide show
  1. alita_sdk/cli/agent/__init__.py +5 -0
  2. alita_sdk/cli/agent/default.py +258 -0
  3. alita_sdk/cli/agent_executor.py +15 -3
  4. alita_sdk/cli/agent_loader.py +56 -8
  5. alita_sdk/cli/agent_ui.py +93 -31
  6. alita_sdk/cli/agents.py +2274 -230
  7. alita_sdk/cli/callbacks.py +96 -25
  8. alita_sdk/cli/cli.py +10 -1
  9. alita_sdk/cli/config.py +162 -9
  10. alita_sdk/cli/context/__init__.py +30 -0
  11. alita_sdk/cli/context/cleanup.py +198 -0
  12. alita_sdk/cli/context/manager.py +731 -0
  13. alita_sdk/cli/context/message.py +285 -0
  14. alita_sdk/cli/context/strategies.py +289 -0
  15. alita_sdk/cli/context/token_estimation.py +127 -0
  16. alita_sdk/cli/input_handler.py +419 -0
  17. alita_sdk/cli/inventory.py +1073 -0
  18. alita_sdk/cli/testcases/__init__.py +94 -0
  19. alita_sdk/cli/testcases/data_generation.py +119 -0
  20. alita_sdk/cli/testcases/discovery.py +96 -0
  21. alita_sdk/cli/testcases/executor.py +84 -0
  22. alita_sdk/cli/testcases/logger.py +85 -0
  23. alita_sdk/cli/testcases/parser.py +172 -0
  24. alita_sdk/cli/testcases/prompts.py +91 -0
  25. alita_sdk/cli/testcases/reporting.py +125 -0
  26. alita_sdk/cli/testcases/setup.py +108 -0
  27. alita_sdk/cli/testcases/test_runner.py +282 -0
  28. alita_sdk/cli/testcases/utils.py +39 -0
  29. alita_sdk/cli/testcases/validation.py +90 -0
  30. alita_sdk/cli/testcases/workflow.py +196 -0
  31. alita_sdk/cli/toolkit.py +14 -17
  32. alita_sdk/cli/toolkit_loader.py +35 -5
  33. alita_sdk/cli/tools/__init__.py +36 -2
  34. alita_sdk/cli/tools/approval.py +224 -0
  35. alita_sdk/cli/tools/filesystem.py +910 -64
  36. alita_sdk/cli/tools/planning.py +389 -0
  37. alita_sdk/cli/tools/terminal.py +414 -0
  38. alita_sdk/community/__init__.py +72 -12
  39. alita_sdk/community/inventory/__init__.py +236 -0
  40. alita_sdk/community/inventory/config.py +257 -0
  41. alita_sdk/community/inventory/enrichment.py +2137 -0
  42. alita_sdk/community/inventory/extractors.py +1469 -0
  43. alita_sdk/community/inventory/ingestion.py +3172 -0
  44. alita_sdk/community/inventory/knowledge_graph.py +1457 -0
  45. alita_sdk/community/inventory/parsers/__init__.py +218 -0
  46. alita_sdk/community/inventory/parsers/base.py +295 -0
  47. alita_sdk/community/inventory/parsers/csharp_parser.py +907 -0
  48. alita_sdk/community/inventory/parsers/go_parser.py +851 -0
  49. alita_sdk/community/inventory/parsers/html_parser.py +389 -0
  50. alita_sdk/community/inventory/parsers/java_parser.py +593 -0
  51. alita_sdk/community/inventory/parsers/javascript_parser.py +629 -0
  52. alita_sdk/community/inventory/parsers/kotlin_parser.py +768 -0
  53. alita_sdk/community/inventory/parsers/markdown_parser.py +362 -0
  54. alita_sdk/community/inventory/parsers/python_parser.py +604 -0
  55. alita_sdk/community/inventory/parsers/rust_parser.py +858 -0
  56. alita_sdk/community/inventory/parsers/swift_parser.py +832 -0
  57. alita_sdk/community/inventory/parsers/text_parser.py +322 -0
  58. alita_sdk/community/inventory/parsers/yaml_parser.py +370 -0
  59. alita_sdk/community/inventory/patterns/__init__.py +61 -0
  60. alita_sdk/community/inventory/patterns/ast_adapter.py +380 -0
  61. alita_sdk/community/inventory/patterns/loader.py +348 -0
  62. alita_sdk/community/inventory/patterns/registry.py +198 -0
  63. alita_sdk/community/inventory/presets.py +535 -0
  64. alita_sdk/community/inventory/retrieval.py +1403 -0
  65. alita_sdk/community/inventory/toolkit.py +173 -0
  66. alita_sdk/community/inventory/toolkit_utils.py +176 -0
  67. alita_sdk/community/inventory/visualize.py +1370 -0
  68. alita_sdk/configurations/__init__.py +1 -1
  69. alita_sdk/configurations/ado.py +141 -20
  70. alita_sdk/configurations/bitbucket.py +0 -3
  71. alita_sdk/configurations/confluence.py +76 -42
  72. alita_sdk/configurations/figma.py +76 -0
  73. alita_sdk/configurations/gitlab.py +17 -5
  74. alita_sdk/configurations/openapi.py +329 -0
  75. alita_sdk/configurations/qtest.py +72 -1
  76. alita_sdk/configurations/report_portal.py +96 -0
  77. alita_sdk/configurations/sharepoint.py +148 -0
  78. alita_sdk/configurations/testio.py +83 -0
  79. alita_sdk/runtime/clients/artifact.py +3 -3
  80. alita_sdk/runtime/clients/client.py +353 -48
  81. alita_sdk/runtime/clients/sandbox_client.py +0 -21
  82. alita_sdk/runtime/langchain/_constants_bkup.py +1318 -0
  83. alita_sdk/runtime/langchain/assistant.py +123 -26
  84. alita_sdk/runtime/langchain/constants.py +642 -1
  85. alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +103 -60
  86. alita_sdk/runtime/langchain/document_loaders/AlitaJSONLinesLoader.py +77 -0
  87. alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +6 -3
  88. alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +226 -7
  89. alita_sdk/runtime/langchain/document_loaders/AlitaTextLoader.py +5 -2
  90. alita_sdk/runtime/langchain/document_loaders/constants.py +12 -7
  91. alita_sdk/runtime/langchain/langraph_agent.py +279 -73
  92. alita_sdk/runtime/langchain/utils.py +82 -15
  93. alita_sdk/runtime/llms/preloaded.py +2 -6
  94. alita_sdk/runtime/skills/__init__.py +91 -0
  95. alita_sdk/runtime/skills/callbacks.py +498 -0
  96. alita_sdk/runtime/skills/discovery.py +540 -0
  97. alita_sdk/runtime/skills/executor.py +610 -0
  98. alita_sdk/runtime/skills/input_builder.py +371 -0
  99. alita_sdk/runtime/skills/models.py +330 -0
  100. alita_sdk/runtime/skills/registry.py +355 -0
  101. alita_sdk/runtime/skills/skill_runner.py +330 -0
  102. alita_sdk/runtime/toolkits/__init__.py +7 -0
  103. alita_sdk/runtime/toolkits/application.py +21 -9
  104. alita_sdk/runtime/toolkits/artifact.py +15 -5
  105. alita_sdk/runtime/toolkits/datasource.py +13 -6
  106. alita_sdk/runtime/toolkits/mcp.py +139 -251
  107. alita_sdk/runtime/toolkits/mcp_config.py +1048 -0
  108. alita_sdk/runtime/toolkits/planning.py +178 -0
  109. alita_sdk/runtime/toolkits/skill_router.py +238 -0
  110. alita_sdk/runtime/toolkits/subgraph.py +251 -6
  111. alita_sdk/runtime/toolkits/tools.py +238 -32
  112. alita_sdk/runtime/toolkits/vectorstore.py +11 -5
  113. alita_sdk/runtime/tools/__init__.py +3 -1
  114. alita_sdk/runtime/tools/application.py +20 -6
  115. alita_sdk/runtime/tools/artifact.py +511 -28
  116. alita_sdk/runtime/tools/data_analysis.py +183 -0
  117. alita_sdk/runtime/tools/function.py +43 -15
  118. alita_sdk/runtime/tools/image_generation.py +50 -44
  119. alita_sdk/runtime/tools/llm.py +852 -67
  120. alita_sdk/runtime/tools/loop.py +3 -1
  121. alita_sdk/runtime/tools/loop_output.py +3 -1
  122. alita_sdk/runtime/tools/mcp_remote_tool.py +25 -10
  123. alita_sdk/runtime/tools/mcp_server_tool.py +7 -6
  124. alita_sdk/runtime/tools/planning/__init__.py +36 -0
  125. alita_sdk/runtime/tools/planning/models.py +246 -0
  126. alita_sdk/runtime/tools/planning/wrapper.py +607 -0
  127. alita_sdk/runtime/tools/router.py +2 -4
  128. alita_sdk/runtime/tools/sandbox.py +9 -6
  129. alita_sdk/runtime/tools/skill_router.py +776 -0
  130. alita_sdk/runtime/tools/tool.py +3 -1
  131. alita_sdk/runtime/tools/vectorstore.py +7 -2
  132. alita_sdk/runtime/tools/vectorstore_base.py +51 -11
  133. alita_sdk/runtime/utils/AlitaCallback.py +137 -21
  134. alita_sdk/runtime/utils/constants.py +5 -1
  135. alita_sdk/runtime/utils/mcp_client.py +492 -0
  136. alita_sdk/runtime/utils/mcp_oauth.py +202 -5
  137. alita_sdk/runtime/utils/mcp_sse_client.py +36 -7
  138. alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
  139. alita_sdk/runtime/utils/serialization.py +155 -0
  140. alita_sdk/runtime/utils/streamlit.py +6 -10
  141. alita_sdk/runtime/utils/toolkit_utils.py +16 -5
  142. alita_sdk/runtime/utils/utils.py +36 -0
  143. alita_sdk/tools/__init__.py +113 -29
  144. alita_sdk/tools/ado/repos/__init__.py +51 -33
  145. alita_sdk/tools/ado/repos/repos_wrapper.py +148 -89
  146. alita_sdk/tools/ado/test_plan/__init__.py +25 -9
  147. alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +23 -1
  148. alita_sdk/tools/ado/utils.py +1 -18
  149. alita_sdk/tools/ado/wiki/__init__.py +25 -8
  150. alita_sdk/tools/ado/wiki/ado_wrapper.py +291 -22
  151. alita_sdk/tools/ado/work_item/__init__.py +26 -9
  152. alita_sdk/tools/ado/work_item/ado_wrapper.py +56 -3
  153. alita_sdk/tools/advanced_jira_mining/__init__.py +11 -8
  154. alita_sdk/tools/aws/delta_lake/__init__.py +13 -9
  155. alita_sdk/tools/aws/delta_lake/tool.py +5 -1
  156. alita_sdk/tools/azure_ai/search/__init__.py +11 -8
  157. alita_sdk/tools/azure_ai/search/api_wrapper.py +1 -1
  158. alita_sdk/tools/base/tool.py +5 -1
  159. alita_sdk/tools/base_indexer_toolkit.py +170 -45
  160. alita_sdk/tools/bitbucket/__init__.py +17 -12
  161. alita_sdk/tools/bitbucket/api_wrapper.py +59 -11
  162. alita_sdk/tools/bitbucket/cloud_api_wrapper.py +49 -35
  163. alita_sdk/tools/browser/__init__.py +5 -4
  164. alita_sdk/tools/carrier/__init__.py +5 -6
  165. alita_sdk/tools/carrier/backend_reports_tool.py +6 -6
  166. alita_sdk/tools/carrier/run_ui_test_tool.py +6 -6
  167. alita_sdk/tools/carrier/ui_reports_tool.py +5 -5
  168. alita_sdk/tools/chunkers/__init__.py +3 -1
  169. alita_sdk/tools/chunkers/code/treesitter/treesitter.py +37 -13
  170. alita_sdk/tools/chunkers/sematic/json_chunker.py +1 -0
  171. alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
  172. alita_sdk/tools/chunkers/universal_chunker.py +270 -0
  173. alita_sdk/tools/cloud/aws/__init__.py +10 -7
  174. alita_sdk/tools/cloud/azure/__init__.py +10 -7
  175. alita_sdk/tools/cloud/gcp/__init__.py +10 -7
  176. alita_sdk/tools/cloud/k8s/__init__.py +10 -7
  177. alita_sdk/tools/code/linter/__init__.py +10 -8
  178. alita_sdk/tools/code/loaders/codesearcher.py +3 -2
  179. alita_sdk/tools/code/sonar/__init__.py +10 -7
  180. alita_sdk/tools/code_indexer_toolkit.py +73 -23
  181. alita_sdk/tools/confluence/__init__.py +21 -15
  182. alita_sdk/tools/confluence/api_wrapper.py +78 -23
  183. alita_sdk/tools/confluence/loader.py +4 -2
  184. alita_sdk/tools/custom_open_api/__init__.py +12 -5
  185. alita_sdk/tools/elastic/__init__.py +11 -8
  186. alita_sdk/tools/elitea_base.py +493 -30
  187. alita_sdk/tools/figma/__init__.py +58 -11
  188. alita_sdk/tools/figma/api_wrapper.py +1235 -143
  189. alita_sdk/tools/figma/figma_client.py +73 -0
  190. alita_sdk/tools/figma/toon_tools.py +2748 -0
  191. alita_sdk/tools/github/__init__.py +13 -14
  192. alita_sdk/tools/github/github_client.py +224 -100
  193. alita_sdk/tools/github/graphql_client_wrapper.py +119 -33
  194. alita_sdk/tools/github/schemas.py +14 -5
  195. alita_sdk/tools/github/tool.py +5 -1
  196. alita_sdk/tools/github/tool_prompts.py +9 -22
  197. alita_sdk/tools/gitlab/__init__.py +15 -11
  198. alita_sdk/tools/gitlab/api_wrapper.py +207 -41
  199. alita_sdk/tools/gitlab_org/__init__.py +10 -8
  200. alita_sdk/tools/gitlab_org/api_wrapper.py +63 -64
  201. alita_sdk/tools/google/bigquery/__init__.py +13 -12
  202. alita_sdk/tools/google/bigquery/tool.py +5 -1
  203. alita_sdk/tools/google_places/__init__.py +10 -8
  204. alita_sdk/tools/google_places/api_wrapper.py +1 -1
  205. alita_sdk/tools/jira/__init__.py +17 -11
  206. alita_sdk/tools/jira/api_wrapper.py +91 -40
  207. alita_sdk/tools/keycloak/__init__.py +11 -8
  208. alita_sdk/tools/localgit/__init__.py +9 -3
  209. alita_sdk/tools/localgit/local_git.py +62 -54
  210. alita_sdk/tools/localgit/tool.py +5 -1
  211. alita_sdk/tools/memory/__init__.py +11 -3
  212. alita_sdk/tools/non_code_indexer_toolkit.py +1 -0
  213. alita_sdk/tools/ocr/__init__.py +11 -8
  214. alita_sdk/tools/openapi/__init__.py +490 -114
  215. alita_sdk/tools/openapi/api_wrapper.py +1368 -0
  216. alita_sdk/tools/openapi/tool.py +20 -0
  217. alita_sdk/tools/pandas/__init__.py +20 -12
  218. alita_sdk/tools/pandas/api_wrapper.py +38 -25
  219. alita_sdk/tools/pandas/dataframe/generator/base.py +3 -1
  220. alita_sdk/tools/postman/__init__.py +11 -11
  221. alita_sdk/tools/pptx/__init__.py +10 -9
  222. alita_sdk/tools/pptx/pptx_wrapper.py +1 -1
  223. alita_sdk/tools/qtest/__init__.py +30 -10
  224. alita_sdk/tools/qtest/api_wrapper.py +430 -13
  225. alita_sdk/tools/rally/__init__.py +10 -8
  226. alita_sdk/tools/rally/api_wrapper.py +1 -1
  227. alita_sdk/tools/report_portal/__init__.py +12 -9
  228. alita_sdk/tools/salesforce/__init__.py +10 -9
  229. alita_sdk/tools/servicenow/__init__.py +17 -14
  230. alita_sdk/tools/servicenow/api_wrapper.py +1 -1
  231. alita_sdk/tools/sharepoint/__init__.py +10 -8
  232. alita_sdk/tools/sharepoint/api_wrapper.py +4 -4
  233. alita_sdk/tools/slack/__init__.py +10 -8
  234. alita_sdk/tools/slack/api_wrapper.py +2 -2
  235. alita_sdk/tools/sql/__init__.py +11 -9
  236. alita_sdk/tools/testio/__init__.py +10 -8
  237. alita_sdk/tools/testrail/__init__.py +11 -8
  238. alita_sdk/tools/testrail/api_wrapper.py +1 -1
  239. alita_sdk/tools/utils/__init__.py +9 -4
  240. alita_sdk/tools/utils/content_parser.py +77 -3
  241. alita_sdk/tools/utils/text_operations.py +410 -0
  242. alita_sdk/tools/utils/tool_prompts.py +79 -0
  243. alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +17 -13
  244. alita_sdk/tools/xray/__init__.py +12 -9
  245. alita_sdk/tools/yagmail/__init__.py +9 -3
  246. alita_sdk/tools/zephyr/__init__.py +9 -7
  247. alita_sdk/tools/zephyr_enterprise/__init__.py +11 -8
  248. alita_sdk/tools/zephyr_essential/__init__.py +10 -8
  249. alita_sdk/tools/zephyr_essential/api_wrapper.py +30 -13
  250. alita_sdk/tools/zephyr_essential/client.py +2 -2
  251. alita_sdk/tools/zephyr_scale/__init__.py +11 -9
  252. alita_sdk/tools/zephyr_scale/api_wrapper.py +2 -2
  253. alita_sdk/tools/zephyr_squad/__init__.py +10 -8
  254. {alita_sdk-0.3.462.dist-info → alita_sdk-0.3.627.dist-info}/METADATA +147 -7
  255. alita_sdk-0.3.627.dist-info/RECORD +468 -0
  256. alita_sdk-0.3.627.dist-info/entry_points.txt +2 -0
  257. alita_sdk-0.3.462.dist-info/RECORD +0 -384
  258. alita_sdk-0.3.462.dist-info/entry_points.txt +0 -2
  259. {alita_sdk-0.3.462.dist-info → alita_sdk-0.3.627.dist-info}/WHEEL +0 -0
  260. {alita_sdk-0.3.462.dist-info → alita_sdk-0.3.627.dist-info}/licenses/LICENSE +0 -0
  261. {alita_sdk-0.3.462.dist-info → alita_sdk-0.3.627.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,5 @@
1
+ """Default agent prompts for Alita CLI."""
2
+
3
+ from .default import DEFAULT_PROMPT
4
+
5
+ __all__ = ['DEFAULT_PROMPT']
@@ -0,0 +1,258 @@
1
+ DEFAULT_PROMPT = """You are **Alita**, a Testing Agent running in a terminal-based CLI assistant. Alita is an open-source, agentic testing interface. You are expected to be precise, safe, technical, and helpful.
2
+
3
+ Your capabilities:
4
+
5
+ - Receive user prompts and other context provided by the harness, such as files in the workspace, logs, test suites, reports, screenshots, API specs, and documentation.
6
+ - Communicate with the user by streaming thinking & responses, and by making & updating plans.
7
+ - Emit function calls to run terminal commands, execute test suites, inspect environments, analyze artifacts, and apply patches when tests require updates. Depending on configuration, you may request that these function calls be escalated for approval before executing.
8
+
9
+ Within this context, **Alita** refers to the open-source agentic testing interface (not any legacy language model).
10
+
11
+ ---
12
+
13
+ # How you work
14
+
15
+ ## Personality
16
+
17
+ You are concise, direct, and friendly. You communicate efficiently and always prioritize actionable test insights. You clearly state assumptions, environment prerequisites, and next steps. Unless explicitly asked, you avoid excessively verbose explanations.
18
+
19
+ ---
20
+
21
+ # AGENTS.md spec
22
+
23
+ `AGENTS.md` files in repositories may contain instructions for working in that specific container — including test conventions, folder structure, naming rules, frameworks in use, test data handling, or how to run validations.
24
+
25
+ Rules:
26
+
27
+ - The scope of an `AGENTS.md` file covers its entire directory subtree.
28
+ - Any file you touch must follow instructions from applicable `AGENTS.md` files.
29
+ - For conflicting instructions, deeper directory `AGENTS.md` takes precedence.
30
+ - Direct system/developer/user instructions always take precedence.
31
+
32
+ ---
33
+
34
+ ## Responsiveness
35
+
36
+ ### Preamble messages
37
+
38
+ Before running tool calls (executing tests, launching commands, applying patches), send a brief preface describing what you’re about to do. It should:
39
+
40
+ - Be short (8–12 words)
41
+ - Group related actions together
42
+ - Refer to previous context when relevant
43
+ - Keep a light and collaborative tone
44
+
45
+ Example patterns:
46
+
47
+ - “Analyzing failing tests next to identify the root cause.”
48
+ - “Running backend API tests now to reproduce the reported issue.”
49
+ - “About to patch selectors and re-run UI regression tests.”
50
+ - “Finished scanning logs; now checking flaky test patterns.”
51
+ - “Next I’ll generate missing test data and rerun.”
52
+
53
+ ---
54
+
55
+ ## Planning
56
+
57
+ Use `update_plan` when:
58
+
59
+ - Tasks involve multiple phases of testing
60
+ - The sequence of activities matters
61
+ - Ambiguity requires breaking down the approach
62
+ - The user requests step-wise execution
63
+
64
+ ### Resuming existing plans
65
+
66
+ **Important**: Before creating a new plan, check if there's already an existing plan in progress:
67
+
68
+ - If the user says "continue" or similar, look at the current plan state shown in tool results
69
+ - If steps are already marked as completed (☑), **do not create a new plan** — continue executing the remaining uncompleted steps
70
+ - Only use `update_plan` to create a **new** plan when starting a fresh task
71
+ - Use `complete_step` to mark steps done as you finish them
72
+
73
+ When resuming after interruption (e.g., tool limit reached):
74
+
75
+ 1. Review which steps are already completed (☑)
76
+ 2. Identify the next uncompleted step (☐)
77
+ 3. Continue execution from that step — do NOT recreate the plan
78
+ 4. Mark steps complete as you go
79
+
80
+ Example of a **high-quality test-oriented plan**:
81
+
82
+ 1. Reproduce failure locally
83
+ 2. Capture failing logs + stack traces
84
+ 3. Identify root cause in test or code
85
+ 4. Patch locator + stabilize assertions
86
+ 5. Run whole suite to confirm no regressions
87
+
88
+ Low-quality plans ("run tests → fix things → done") are not acceptable.
89
+
90
+ ---
91
+
92
+ ## Task execution
93
+
94
+ You are a **testing agent**, not just a code-writing agent. Your responsibilities include:
95
+
96
+ - Executing tests across frameworks (API, UI, mobile, backend, contract, load, security)
97
+ - Analyzing logs, failures, screenshots, metrics, stack traces
98
+ - Investigating flakiness, nondeterminism, environmental issues
99
+ - Generating missing tests or aligning test coverage to requirements
100
+ - Proposing (and applying when asked) patches to fix the root cause of test failures
101
+ - Updating and creating test cases, fixtures, mocks, test data and configs
102
+ - Validating integrations (CI/CD, containers, runners, environments)
103
+ - Surfacing reliability and coverage gaps
104
+
105
+ When applying patches, follow repository style and AGENTS.md rules.
106
+ Avoid modifying unrelated code and avoid adding technical debt.
107
+
108
+ Common use cases include:
109
+
110
+ - Test execution automation
111
+ - Manual exploratory testing documentation
112
+ - Test case generation from requirements
113
+ - Assertions improvements and selector stabilization
114
+ - Test coverage analysis
115
+ - Defect reproduction and debugging
116
+ - Root cause attribution (test vs product defect)
117
+
118
+ ---
119
+
120
+ ## Handling files
121
+
122
+ ### CRITICAL: File creation and modification rules
123
+
124
+ **NEVER output entire file contents in your response.** Always use tools to write files.
125
+
126
+ When creating or modifying files:
127
+
128
+ 1. **Use incremental writes for new files**: Create files in logical sections using multiple tool calls:
129
+ - First call: Create file with initial structure (imports, class definition header)
130
+ - Subsequent calls: Add methods, functions, or sections one at a time using edit/append
131
+ - This prevents context overflow and ensures each part is properly written
132
+
133
+ 2. **Use edit tools for modifications**: Use `filesystem_edit_file` for precise text replacement instead of rewriting entire files
134
+
135
+ 3. **Never dump code in chat**: If you find yourself about to write a large code block in your response, STOP and use a file tool instead
136
+
137
+ Example - creating a test file correctly:
138
+ ```
139
+ # Call 1: Create file with structure
140
+ filesystem_write_file("test_api.py", "import pytest\\nimport requests\\n\\n")
141
+
142
+ # Call 2: Append first test class/method
143
+ filesystem_append_file("test_api.py", "class TestAPI:\\n def test_health(self):\\n assert requests.get('/health').status_code == 200\\n")
144
+
145
+ # Call 3: Append second test method
146
+ filesystem_append_file("test_api.py", "\\n def test_auth(self):\\n assert requests.get('/protected').status_code == 401\\n")
147
+ ```
148
+
149
+ **Why this matters**: Large file outputs can exceed token limits, cause truncation, or fail silently. Incremental writes are reliable and verifiable.
150
+
151
+ ### Reading large files
152
+
153
+ When working with large files (logs, test reports, data files, source code):
154
+
155
+ - **Read in chunks**: Use offset and limit parameters to read files in manageable sections (e.g., 500-1000 lines at a time)
156
+ - **Start with structure**: First scan the file to understand its layout before diving into specific sections
157
+ - **Target relevant sections**: Once you identify the area of interest, read only that portion in detail
158
+ - **Avoid full loads**: Loading entire large files into context can cause models to return empty or incomplete responses due to context limitations
159
+
160
+ Example approach:
161
+ 1. Read first 100 lines to understand file structure
162
+ 2. Search/grep for relevant patterns to locate target sections
163
+ 3. Read specific line ranges where issues or relevant code exist
164
+
165
+ ### Writing and updating files
166
+
167
+ When modifying files, especially large ones:
168
+
169
+ - **Update in pieces**: Make targeted edits to specific sections, paragraphs, or functions rather than rewriting entire files
170
+ - **Use precise replacements**: Replace exact strings with sufficient context (3-5 lines before/after) to ensure unique matches
171
+ - **Batch related changes**: Group logically related edits together, but keep each edit focused and minimal
172
+ - **Preserve structure**: Maintain existing formatting, indentation, and file organization
173
+ - **Avoid full rewrites**: Never regenerate an entire file when only a portion needs changes
174
+
175
+ ### Context limitations warning
176
+
177
+ **Important**: When context becomes too large (many files, long outputs, extensive history), some models may return empty or truncated responses. If you notice this:
178
+
179
+ - Summarize previous findings before continuing
180
+ - Focus on one file or task at a time
181
+ - Clear irrelevant context from consideration
182
+ - Break complex operations into smaller, sequential steps
183
+
184
+ ---
185
+
186
+ ## Sandbox and approvals
187
+
188
+ Sandboxing and approval rules are identical to coding agents, but framed around testing actions:
189
+
190
+ You may need escalation before:
191
+
192
+ - Creating or modifying files
193
+ - Installing testing dependencies
194
+ - Running network-dependent test suites
195
+ - Performing destructive cleanup actions
196
+ - Triggering CI pipelines or test runs that write outside workspace
197
+
198
+ If sandbox modes and approval rules are not specified, assume:
199
+
200
+ - Filesystem: `workspace-write`
201
+ - Network: ON
202
+ - Approval: `on-failure`
203
+
204
+ ---
205
+
206
+ ## Validating your work
207
+
208
+ Validation is core to your job.
209
+
210
+ - After fixing tests, rerun only the relevant subset first
211
+ - If stable, run broader suites to validate no regressions
212
+ - Avoid running full suites unnecessarily when in approval modes that require escalation
213
+
214
+ If there are no tests for the change you made, and the project has an established testing pattern, you may add one.
215
+
216
+ Avoid fixing unrelated tests unless the user requests it.
217
+
218
+ ---
219
+
220
+ ## Presenting your work and final message
221
+
222
+ Your final message should feel like an update from a senior test engineer handing off state.
223
+
224
+ Good patterns include:
225
+
226
+ - What was tested
227
+ - What failed and why
228
+ - What was fixed
229
+ - Where files were changed
230
+ - How to validate locally
231
+
232
+ You should not dump full file contents unless the user asks. Reference files and paths directly.
233
+
234
+ If relevant, offer optional next steps such as:
235
+
236
+ - Running full regression
237
+ - Adding missing tests
238
+ - Improving coverage or performance
239
+ - Integrating into CI
240
+
241
+ ---
242
+
243
+ ## Answer formatting rules in CLI
244
+
245
+ Keep results scannable and technical:
246
+
247
+ - Use section headers only where they improve clarity
248
+ - Use short bullet lists (4–6 key bullets)
249
+ - Use backticks for code, commands, test names, file paths
250
+ - Reference files individually to keep them clickable (e.g. `tests/ui/login.spec.ts:44`)
251
+ - Avoid nested bullet lists or long paragraphs
252
+
253
+ Tone: pragmatic, precise, and focused on improving testing reliability and coverage.
254
+
255
+ ---
256
+
257
+ In short: **Alita is a highly technical manual + automated testing agent** that plans intelligently, executes and analyzes tests across frameworks, fixes issues at their root when permitted, and keeps the user informed without noise.
258
+ """
@@ -58,13 +58,15 @@ def _create_assistant(client, agent_data: Dict[str, Any], llm, memory, tools: Li
58
58
  memory=memory,
59
59
  store=None,
60
60
  debug_mode=False,
61
- mcp_tokens=None
61
+ mcp_tokens=None,
62
+ persona=agent_data.get('persona', 'quirky'),
62
63
  )
63
64
 
64
65
 
65
66
  def create_agent_executor(client, agent_def: Dict[str, Any], toolkit_configs: List[Dict[str, Any]],
66
67
  llm, llm_model: str, llm_temperature: float, llm_max_tokens: int, memory,
67
- filesystem_tools: Optional[List] = None, mcp_tools: Optional[List] = None):
68
+ filesystem_tools: Optional[List] = None, mcp_tools: Optional[List] = None,
69
+ terminal_tools: Optional[List] = None, planning_tools: Optional[List] = None):
68
70
  """Create agent executor for local agents with tools (sync version).
69
71
 
70
72
  Note: mcp_tools parameter is deprecated - use create_agent_executor_with_mcp for MCP support.
@@ -81,6 +83,10 @@ def create_agent_executor(client, agent_def: Dict[str, Any], toolkit_configs: Li
81
83
  additional_tools = []
82
84
  if filesystem_tools:
83
85
  additional_tools.extend(filesystem_tools)
86
+ if terminal_tools:
87
+ additional_tools.extend(terminal_tools)
88
+ if planning_tools:
89
+ additional_tools.extend(planning_tools)
84
90
  if mcp_tools:
85
91
  additional_tools.extend(mcp_tools)
86
92
 
@@ -97,7 +103,9 @@ async def create_agent_executor_with_mcp(
97
103
  llm_temperature: float,
98
104
  llm_max_tokens: int,
99
105
  memory,
100
- filesystem_tools: Optional[List] = None
106
+ filesystem_tools: Optional[List] = None,
107
+ terminal_tools: Optional[List] = None,
108
+ planning_tools: Optional[List] = None
101
109
  ) -> Tuple[Any, Optional[Any]]:
102
110
  """Create agent executor with MCP tools using persistent sessions.
103
111
 
@@ -135,6 +143,10 @@ async def create_agent_executor_with_mcp(
135
143
  additional_tools = []
136
144
  if filesystem_tools:
137
145
  additional_tools.extend(filesystem_tools)
146
+ if terminal_tools:
147
+ additional_tools.extend(terminal_tools)
148
+ if planning_tools:
149
+ additional_tools.extend(planning_tools)
138
150
  if mcp_tools:
139
151
  additional_tools.extend(mcp_tools)
140
152
 
@@ -5,13 +5,42 @@ Handles loading agent definitions from various file formats (YAML, JSON, Markdow
5
5
  """
6
6
 
7
7
  import json
8
+ import locale
8
9
  import yaml
9
10
  from pathlib import Path
10
11
  from typing import Dict, Any
12
+ from pydantic import SecretStr
11
13
 
12
14
  from .config import substitute_env_vars
13
15
 
14
16
 
17
+ def _read_text_with_fallbacks(path: Path) -> str:
18
+ """Read a text file using robust, cross-platform defaults.
19
+
20
+ Why this exists:
21
+ - On Windows, `Path.read_text()` defaults to the system code page (often cp1252).
22
+ Agent definition files are commonly authored as UTF-8 and may include smart quotes
23
+ (e.g. ”) whose UTF-8 byte sequence contains 0x9D, which is *undefined* in cp1252.
24
+ That combination triggers: UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d.
25
+ """
26
+
27
+ # 1) Prefer UTF-8 (most common for repo files)
28
+ try:
29
+ return path.read_text(encoding="utf-8")
30
+ except UnicodeDecodeError:
31
+ pass
32
+
33
+ # 2) UTF-8 with BOM (common on Windows)
34
+ try:
35
+ return path.read_text(encoding="utf-8-sig")
36
+ except UnicodeDecodeError:
37
+ pass
38
+
39
+ # 3) Fall back to the platform preferred encoding, but never crash.
40
+ # This keeps the CLI usable even if a file was authored in a legacy encoding.
41
+ return path.read_text(encoding=locale.getpreferredencoding(False), errors="replace")
42
+
43
+
15
44
  def load_agent_definition(file_path: str) -> Dict[str, Any]:
16
45
  """
17
46
  Load agent definition from file.
@@ -31,8 +60,8 @@ def load_agent_definition(file_path: str) -> Dict[str, Any]:
31
60
 
32
61
  if not path.exists():
33
62
  raise FileNotFoundError(f"Agent definition not found: {file_path}")
34
-
35
- content = path.read_text()
63
+
64
+ content = _read_text_with_fallbacks(path)
36
65
 
37
66
  # Handle markdown with YAML frontmatter
38
67
  if path.suffix == '.md':
@@ -57,7 +86,8 @@ def load_agent_definition(file_path: str) -> Dict[str, Any]:
57
86
  'filesystem_tools_preset': frontmatter.get('filesystem_tools_preset'),
58
87
  'filesystem_tools_include': frontmatter.get('filesystem_tools_include'),
59
88
  'filesystem_tools_exclude': frontmatter.get('filesystem_tools_exclude'),
60
- 'mcps': frontmatter.get('mcps', [])
89
+ 'mcps': frontmatter.get('mcps', []),
90
+ 'persona': frontmatter.get('persona')
61
91
  }
62
92
 
63
93
  # Plain markdown - use content as system prompt
@@ -85,6 +115,25 @@ def load_agent_definition(file_path: str) -> Dict[str, Any]:
85
115
  raise ValueError(f"Unsupported file format: {path.suffix}")
86
116
 
87
117
 
118
+ def unwrap_secrets(obj: Any) -> Any:
119
+ """
120
+ Recursively unwrap pydantic SecretStr values into plain strings.
121
+
122
+ Handles nested dicts, lists, tuples, and sets while preserving structure.
123
+ """
124
+ if isinstance(obj, SecretStr):
125
+ return obj.get_secret_value()
126
+ if isinstance(obj, dict):
127
+ return {k: unwrap_secrets(v) for k, v in obj.items()}
128
+ if isinstance(obj, list):
129
+ return [unwrap_secrets(v) for v in obj]
130
+ if isinstance(obj, tuple):
131
+ return tuple(unwrap_secrets(v) for v in obj)
132
+ if isinstance(obj, set):
133
+ return {unwrap_secrets(v) for v in obj}
134
+ return obj
135
+
136
+
88
137
  def build_agent_data_structure(agent_def: Dict[str, Any], toolkit_configs: list,
89
138
  llm_model: str, llm_temperature: float, llm_max_tokens: int) -> Dict[str, Any]:
90
139
  """
@@ -128,7 +177,8 @@ def build_agent_data_structure(agent_def: Dict[str, Any], toolkit_configs: list,
128
177
  if hasattr(toolkit_class, 'toolkit_config_schema'):
129
178
  schema = toolkit_class.toolkit_config_schema()
130
179
  validated_config = schema(**toolkit_config)
131
- validated_dict = validated_config.model_dump()
180
+ # Use python mode so SecretStr remains as objects, then unwrap recursively
181
+ validated_dict = unwrap_secrets(validated_config.model_dump(mode="python"))
132
182
  validated_dict['type'] = toolkit_config.get('type')
133
183
  validated_dict['toolkit_name'] = toolkit_config.get('toolkit_name')
134
184
  validated_toolkit_configs.append(validated_dict)
@@ -168,7 +218,6 @@ def build_agent_data_structure(agent_def: Dict[str, Any], toolkit_configs: list,
168
218
  'settings': toolkit_config,
169
219
  'selected_tools': toolkit_config.get('selected_tools', [])
170
220
  })
171
-
172
221
  return {
173
222
  'instructions': agent_def.get('system_prompt', ''),
174
223
  'tools': tools,
@@ -181,8 +230,6 @@ def build_agent_data_structure(agent_def: Dict[str, Any], toolkit_configs: list,
181
230
  'model_name': llm_model,
182
231
  'max_tokens': llm_max_tokens,
183
232
  'temperature': llm_temperature,
184
- 'top_p': 1.0,
185
- 'top_k': 0,
186
233
  'integration_uid': None,
187
234
  'indexer_config': {
188
235
  'ai_model': 'langchain_openai.ChatOpenAI',
@@ -193,5 +240,6 @@ def build_agent_data_structure(agent_def: Dict[str, Any], toolkit_configs: list,
193
240
  }
194
241
  }
195
242
  },
196
- 'agent_type': agent_def.get('agent_type', 'react')
243
+ 'agent_type': agent_def.get('agent_type', 'react'),
244
+ 'persona': agent_def.get('persona', 'quirky')
197
245
  }
alita_sdk/cli/agent_ui.py CHANGED
@@ -79,12 +79,23 @@ def print_help():
79
79
  padding=(0, 1),
80
80
  )
81
81
 
82
- table.add_column("Command", style="bold yellow", no_wrap=True, width=12)
82
+ table.add_column("Command", style="bold yellow", no_wrap=True, width=16)
83
83
  table.add_column("Description", style="white")
84
84
 
85
85
  table.add_row("/clear", "Clear conversation history")
86
86
  table.add_row("/history", "Show conversation history")
87
87
  table.add_row("/save", "Save conversation to file")
88
+ table.add_row("/agent", "Switch to a different agent or direct chat")
89
+ table.add_row("/model", "Switch to a different model (preserves history)")
90
+ table.add_row("/reload", "Reload agent from file (hot reload)")
91
+ table.add_row("/mode", "Set approval mode: always, auto, yolo")
92
+ table.add_row("/dir [add|rm] <path>", "Add/remove/list allowed directories")
93
+ table.add_row("/inventory <path>", "Load inventory/knowledge graph from JSON file")
94
+ table.add_row("/session", "List or resume previous sessions with plans")
95
+ table.add_row("/add_mcp", "Add an MCP server (preserves history)")
96
+ table.add_row("/add_toolkit", "Add a toolkit (preserves history)")
97
+ table.add_row("/rm_mcp", "Remove an MCP server")
98
+ table.add_row("/rm_toolkit", "Remove a toolkit")
88
99
  table.add_row("/help", "Show this help")
89
100
  table.add_row("exit", "End conversation")
90
101
 
@@ -92,55 +103,106 @@ def print_help():
92
103
  console.print()
93
104
 
94
105
 
95
- def print_welcome(agent_name: str, agent_type: str = "Local Agent"):
96
- """Print combined welcome banner with logo, agent info, and help."""
106
+ def print_welcome(agent_name: str, model: str = "gpt-4o", temperature: float = 0.1, mode: str = "always"):
107
+ """Print combined welcome banner with logo, agent info, and help in two columns."""
97
108
 
98
109
  version = get_version()
99
110
 
100
- # Build the complete welcome message using Text objects
101
- content = Text()
111
+ # Mode display with color
112
+ mode_colors = {'always': 'yellow', 'auto': 'green', 'yolo': 'red'}
113
+ mode_color = mode_colors.get(mode, 'white')
102
114
 
103
- # Add logo lines with cyan styling
115
+ # Left column: Logo + version + agent info
116
+ left_content = Text()
104
117
  for line in ALITA_LOGO:
105
- content.append(" " + line + "\n", style="bold cyan")
106
-
107
- content.append(" CLI ", style="dim")
108
- content.append(f"v{version}\n\n", style="bold white")
109
-
110
- # Connection status
111
- content.append(" ● ", style="bold green")
112
- content.append("Agent: ", style="bold white")
113
- content.append(f"{agent_name}\n", style="bold cyan")
114
- content.append(" ", style="bold green")
115
- content.append("Type: ", style="bold white")
116
- content.append(f"{agent_type}\n\n", style="cyan")
117
-
118
- # Quick help section
119
- content.append(" Type a message to chat, or use these commands:\n\n", style="dim")
120
-
121
- # Commands
122
- content.append(" /help", style="bold yellow")
123
- content.append(" Show all commands\n", style="white")
124
- content.append(" /clear", style="bold yellow")
125
- content.append(" Clear history\n", style="white")
126
- content.append(" exit", style="bold yellow")
127
- content.append(" End conversation\n", style="white")
118
+ left_content.append(line + "\n", style="bold cyan")
119
+ left_content.append(" CLI ", style="dim")
120
+ left_content.append(f"v{version}\n\n", style="bold white")
121
+ left_content.append("", style="bold green")
122
+ left_content.append("Agent: ", style="bold white")
123
+ left_content.append(f"{agent_name}\n", style="bold cyan")
124
+ left_content.append("● ", style="bold green")
125
+ left_content.append("Model: ", style="bold white")
126
+ left_content.append(f"{model}", style="cyan")
127
+ left_content.append(" | ", style="dim")
128
+ left_content.append("Temp: ", style="bold white")
129
+ left_content.append(f"{temperature}\n", style="cyan")
130
+ left_content.append("● ", style="bold green")
131
+ left_content.append("Mode: ", style="bold white")
132
+ left_content.append(f"{mode}\n", style=f"bold {mode_color}")
133
+
134
+ # Right column: Commands
135
+ right_content = Text()
136
+ right_content.append("\n") # Align with logo
137
+ right_content.append("/help", style="bold yellow")
138
+ right_content.append(" Show all commands\n", style="dim")
139
+ right_content.append("/agent", style="bold yellow")
140
+ right_content.append(" Switch agent\n", style="dim")
141
+ right_content.append("/model", style="bold yellow")
142
+ right_content.append(" Switch model\n", style="dim")
143
+ right_content.append("/reload", style="bold yellow")
144
+ right_content.append(" Reload agent file\n", style="dim")
145
+ right_content.append("/mode", style="bold yellow")
146
+ right_content.append(" Set approval mode\n", style="dim")
147
+ right_content.append("/dir", style="bold yellow")
148
+ right_content.append(" Add/list directories\n", style="dim")
149
+ right_content.append("/session", style="bold yellow")
150
+ right_content.append(" List/resume sessions\n", style="dim")
151
+ right_content.append("/inventory", style="bold yellow")
152
+ right_content.append(" Load knowledge graph\n", style="dim")
153
+ right_content.append("/add_mcp", style="bold yellow")
154
+ right_content.append(" Add MCP server\n", style="dim")
155
+ right_content.append("/add_toolkit", style="bold yellow")
156
+ right_content.append(" Add toolkit\n", style="dim")
157
+ right_content.append("exit", style="bold yellow")
158
+ right_content.append(" End conversation\n", style="dim")
159
+
160
+ # Create two-column layout
161
+ columns = Columns([left_content, right_content], padding=(0, 4), expand=False)
128
162
 
129
163
  console.print()
130
164
  console.print(Panel(
131
- content,
165
+ columns,
132
166
  box=box.DOUBLE,
133
167
  border_style="cyan",
134
- padding=(0, 2),
168
+ padding=(1, 2),
135
169
  ))
136
170
  console.print()
137
171
 
138
172
 
173
+ def render_plan(plan_state) -> None:
174
+ """Render a plan with checkboxes."""
175
+ if not plan_state or not plan_state.steps:
176
+ return
177
+
178
+ console.print(plan_state.render())
179
+ console.print()
180
+
181
+
182
+ def render_approval_prompt(tool_name: str, tool_args: dict, truncate: int = 60) -> str:
183
+ """
184
+ Render an approval prompt for a tool call.
185
+
186
+ Returns the formatted string for display in the input box.
187
+ """
188
+ # Format args as a compact string
189
+ args_str = ", ".join(f"{k}={repr(v)[:truncate]}" for k, v in tool_args.items())
190
+ if len(args_str) > 80:
191
+ args_str = args_str[:77] + "..."
192
+
193
+ return f"🔧 {tool_name}: {args_str}"
194
+
195
+
139
196
  def display_output(agent_name: str, message: str, output: str):
140
197
  """Display agent output with markdown rendering if applicable."""
141
198
  console.print(f"\n[bold cyan]🤖 Agent: {agent_name}[/bold cyan]\n")
142
199
  console.print(f"[bold]Message:[/bold] {message}\n")
143
200
  console.print("[bold]Response:[/bold]")
201
+
202
+ # Ensure output is a string
203
+ if not isinstance(output, str):
204
+ output = str(output)
205
+
144
206
  if any(marker in output for marker in ['```', '**', '##', '- ', '* ']):
145
207
  console.print(Markdown(output))
146
208
  else: