alita-sdk 0.3.449__py3-none-any.whl → 0.3.465__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.

Potentially problematic release.


This version of alita-sdk might be problematic. Click here for more details.

Files changed (74) hide show
  1. alita_sdk/cli/__init__.py +10 -0
  2. alita_sdk/cli/__main__.py +17 -0
  3. alita_sdk/cli/agent/__init__.py +0 -0
  4. alita_sdk/cli/agent/default.py +176 -0
  5. alita_sdk/cli/agent_executor.py +155 -0
  6. alita_sdk/cli/agent_loader.py +197 -0
  7. alita_sdk/cli/agent_ui.py +218 -0
  8. alita_sdk/cli/agents.py +1911 -0
  9. alita_sdk/cli/callbacks.py +576 -0
  10. alita_sdk/cli/cli.py +159 -0
  11. alita_sdk/cli/config.py +164 -0
  12. alita_sdk/cli/formatting.py +182 -0
  13. alita_sdk/cli/input_handler.py +256 -0
  14. alita_sdk/cli/mcp_loader.py +315 -0
  15. alita_sdk/cli/toolkit.py +330 -0
  16. alita_sdk/cli/toolkit_loader.py +55 -0
  17. alita_sdk/cli/tools/__init__.py +36 -0
  18. alita_sdk/cli/tools/approval.py +224 -0
  19. alita_sdk/cli/tools/filesystem.py +905 -0
  20. alita_sdk/cli/tools/planning.py +403 -0
  21. alita_sdk/cli/tools/terminal.py +280 -0
  22. alita_sdk/runtime/clients/client.py +16 -1
  23. alita_sdk/runtime/langchain/constants.py +2 -1
  24. alita_sdk/runtime/langchain/langraph_agent.py +74 -20
  25. alita_sdk/runtime/langchain/utils.py +20 -4
  26. alita_sdk/runtime/toolkits/artifact.py +5 -6
  27. alita_sdk/runtime/toolkits/mcp.py +5 -2
  28. alita_sdk/runtime/toolkits/tools.py +1 -0
  29. alita_sdk/runtime/tools/function.py +19 -6
  30. alita_sdk/runtime/tools/llm.py +65 -7
  31. alita_sdk/runtime/tools/vectorstore_base.py +17 -2
  32. alita_sdk/runtime/utils/mcp_sse_client.py +64 -6
  33. alita_sdk/tools/ado/repos/__init__.py +1 -0
  34. alita_sdk/tools/ado/test_plan/__init__.py +1 -1
  35. alita_sdk/tools/ado/wiki/__init__.py +1 -5
  36. alita_sdk/tools/ado/work_item/__init__.py +1 -5
  37. alita_sdk/tools/base_indexer_toolkit.py +64 -8
  38. alita_sdk/tools/bitbucket/__init__.py +1 -0
  39. alita_sdk/tools/code/sonar/__init__.py +1 -1
  40. alita_sdk/tools/confluence/__init__.py +2 -2
  41. alita_sdk/tools/github/__init__.py +2 -2
  42. alita_sdk/tools/gitlab/__init__.py +2 -1
  43. alita_sdk/tools/gitlab_org/__init__.py +1 -2
  44. alita_sdk/tools/google_places/__init__.py +2 -1
  45. alita_sdk/tools/jira/__init__.py +1 -0
  46. alita_sdk/tools/memory/__init__.py +1 -1
  47. alita_sdk/tools/pandas/__init__.py +1 -1
  48. alita_sdk/tools/postman/__init__.py +2 -1
  49. alita_sdk/tools/pptx/__init__.py +2 -2
  50. alita_sdk/tools/qtest/__init__.py +3 -3
  51. alita_sdk/tools/qtest/api_wrapper.py +1235 -51
  52. alita_sdk/tools/rally/__init__.py +1 -2
  53. alita_sdk/tools/report_portal/__init__.py +1 -0
  54. alita_sdk/tools/salesforce/__init__.py +1 -0
  55. alita_sdk/tools/servicenow/__init__.py +2 -3
  56. alita_sdk/tools/sharepoint/__init__.py +1 -0
  57. alita_sdk/tools/sharepoint/api_wrapper.py +22 -2
  58. alita_sdk/tools/sharepoint/authorization_helper.py +17 -1
  59. alita_sdk/tools/slack/__init__.py +1 -0
  60. alita_sdk/tools/sql/__init__.py +2 -1
  61. alita_sdk/tools/testio/__init__.py +1 -0
  62. alita_sdk/tools/testrail/__init__.py +1 -3
  63. alita_sdk/tools/xray/__init__.py +2 -1
  64. alita_sdk/tools/zephyr/__init__.py +2 -1
  65. alita_sdk/tools/zephyr_enterprise/__init__.py +1 -0
  66. alita_sdk/tools/zephyr_essential/__init__.py +1 -0
  67. alita_sdk/tools/zephyr_scale/__init__.py +1 -0
  68. alita_sdk/tools/zephyr_squad/__init__.py +1 -0
  69. {alita_sdk-0.3.449.dist-info → alita_sdk-0.3.465.dist-info}/METADATA +145 -2
  70. {alita_sdk-0.3.449.dist-info → alita_sdk-0.3.465.dist-info}/RECORD +74 -52
  71. alita_sdk-0.3.465.dist-info/entry_points.txt +2 -0
  72. {alita_sdk-0.3.449.dist-info → alita_sdk-0.3.465.dist-info}/WHEEL +0 -0
  73. {alita_sdk-0.3.449.dist-info → alita_sdk-0.3.465.dist-info}/licenses/LICENSE +0 -0
  74. {alita_sdk-0.3.449.dist-info → alita_sdk-0.3.465.dist-info}/top_level.txt +0 -0
@@ -29,8 +29,6 @@ class RallyToolkit(BaseToolkit):
29
29
  RallyToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
30
30
  return create_model(
31
31
  name,
32
- name=(str, Field(description="Toolkit name", json_schema_extra={'toolkit_name': True,
33
- 'max_toolkit_length': RallyToolkit.toolkit_max_length})),
34
32
  rally_configuration=(RallyConfiguration, Field(description="Rally configuration", json_schema_extra={'configuration_types': ['rally']})),
35
33
  workspace=(Optional[str], Field(default=None, description="Rally workspace")),
36
34
  project=(Optional[str], Field(default=None, description="Rally project")),
@@ -39,6 +37,7 @@ class RallyToolkit(BaseToolkit):
39
37
  'metadata': {
40
38
  "label": "Rally",
41
39
  "icon_url": "rally.svg",
40
+ "max_length": RallyToolkit.toolkit_max_length,
42
41
  "categories": ["project management"],
43
42
  "extra_categories": ["agile management", "test management", "scrum", "kanban"]
44
43
  }
@@ -33,6 +33,7 @@ class ReportPortalToolkit(BaseToolkit):
33
33
  report_portal_configuration=(ReportPortalConfiguration, Field(description="Report Portal Configuration", json_schema_extra={'configuration_types': ['report_portal']})),
34
34
  selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
35
35
  __config__=ConfigDict(json_schema_extra={'metadata': {"label": "Report Portal", "icon_url": "reportportal-icon.svg",
36
+ "max_length": ReportPortalToolkit.toolkit_max_length,
36
37
  "categories": ["testing"],
37
38
  "extra_categories": ["test reporting", "test automation"]}})
38
39
  )
@@ -31,6 +31,7 @@ class SalesforceToolkit(BaseToolkit):
31
31
  selected_tools=(List[Literal[tuple(available_tools)]], Field(default=[], json_schema_extra={'args_schemas': available_tools})),
32
32
  __config__=ConfigDict(json_schema_extra={'metadata': {
33
33
  "label": "Salesforce", "icon_url": "salesforce-icon.svg",
34
+ "max_length": SalesforceToolkit.toolkit_max_length,
34
35
  "categories": ["other"],
35
36
  "extra_categories": ["customer relationship management", "cloud computing", "marketing automation", "salesforce"]
36
37
  }})
@@ -35,9 +35,7 @@ class ServiceNowToolkit(BaseToolkit):
35
35
  ServiceNowToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
36
36
  return create_model(
37
37
  name,
38
- name=(str, Field(description="Toolkit name",
39
- json_schema_extra={
40
- 'toolkit_name': True, 'max_toolkit_length': ServiceNowToolkit.toolkit_max_length})),
38
+ name=(str, Field(description="Toolkit name")),
41
39
  response_fields=(Optional[str], Field(description="Response fields", default=None)),
42
40
  servicenow_configuration=(ServiceNowConfiguration, Field(description="ServiceNow Configuration",
43
41
  json_schema_extra={
@@ -49,6 +47,7 @@ class ServiceNowToolkit(BaseToolkit):
49
47
  'metadata': {
50
48
  "label": "ServiceNow",
51
49
  "icon_url": "service-now.svg",
50
+ "max_length": ServiceNowToolkit.toolkit_max_length,
52
51
  "hidden": False,
53
52
  "sections": {
54
53
  "auth": {
@@ -48,6 +48,7 @@ class SharepointToolkit(BaseToolkit):
48
48
  __config__=ConfigDict(json_schema_extra={
49
49
  'metadata': {
50
50
  "label": "Sharepoint", "icon_url": "sharepoint.svg",
51
+ "max_length": SharepointToolkit.toolkit_max_length,
51
52
  "categories": ["office"],
52
53
  "extra_categories": ["microsoft", "cloud storage", "team collaboration", "content management"]
53
54
  }})
@@ -130,9 +130,24 @@ class SharepointApiWrapper(NonCodeIndexerToolkit):
130
130
  if not limit_files:
131
131
  limit_files = 100
132
132
  #
133
+ site_segments = [seg for seg in self.site_url.strip('/').split('/') if seg][-2:]
134
+ full_path_prefix = '/'.join(site_segments)
135
+ #
133
136
  for lib in all_libraries:
134
137
  library_type = decode_sharepoint_string(lib.properties["EntityTypeName"])
135
- target_folder_url = f"{library_type}/{folder_name}" if folder_name else library_type
138
+ target_folder_url = library_type
139
+ if folder_name:
140
+ folder_path = folder_name.strip('/')
141
+ expected_prefix = f'{full_path_prefix}/{library_type}'
142
+ if folder_path.startswith(full_path_prefix):
143
+ if folder_path.startswith(expected_prefix):
144
+ target_folder_url = folder_path.removeprefix(f'{full_path_prefix}/')
145
+ else:
146
+ # ignore full path folder which is not targeted to current library
147
+ continue
148
+ else:
149
+ target_folder_url = f"{library_type}/{folder_name}"
150
+ #
136
151
  files = (self._client.web.get_folder_by_server_relative_path(target_folder_url)
137
152
  .get_files(True)
138
153
  .execute_query())
@@ -226,13 +241,18 @@ class SharepointApiWrapper(NonCodeIndexerToolkit):
226
241
  'skip_extensions': (Optional[List[str]], Field(
227
242
  description="List of file extensions to skip when processing: i.e. ['*.png', '*.jpg']",
228
243
  default=[])),
244
+ 'path': (Optional[str], Field(
245
+ description="Folder path. "
246
+ "Accepts either a full server-relative path (e.g., '/sites/SiteName/...') or a relative path. "
247
+ "If a relative path is provided, the search will be performed recursively under 'Shared Documents' and other private libraries.",
248
+ default=None)),
229
249
  }
230
250
 
231
251
  def _base_loader(self, **kwargs) -> Generator[Document, None, None]:
232
252
 
233
253
  self._log_tool_event(message="Starting SharePoint files extraction", tool_name="loader")
234
254
  try:
235
- all_files = self.get_files_list(limit_files=kwargs.get('limit_files', 10000))
255
+ all_files = self.get_files_list(kwargs.get('path'), kwargs.get('limit_files', 10000))
236
256
  self._log_tool_event(message="List of the files has been extracted", tool_name="loader")
237
257
  except Exception as e:
238
258
  raise ToolException(f"Unable to extract files: {e}")
@@ -147,12 +147,28 @@ class SharepointAuthorizationHelper:
147
147
  if limit_files is not None and len(result) + len(files) >= limit_files:
148
148
  return files[:limit_files - len(result)]
149
149
  return files
150
+ #
151
+ site_segments = [seg for seg in site_url.strip('/').split('/') if seg][-2:]
152
+ full_path_prefix = '/'.join(site_segments)
153
+ #
150
154
  for drive in drives:
151
155
  drive_id = drive.get("id")
152
156
  drive_path = unquote(urlparse(drive.get("webUrl")).path) if drive.get("webUrl") else ""
153
157
  if not drive_id:
154
158
  continue # skip drives without id
155
- files = _recurse_drive(drive_id, drive_path, folder_name, limit_files)
159
+ #
160
+ sub_folder = folder_name
161
+ if folder_name:
162
+ folder_path = folder_name.strip('/')
163
+ expected_prefix = drive_path.strip('/')#f'{full_path_prefix}/{library_type}'
164
+ if folder_path.startswith(full_path_prefix):
165
+ if folder_path.startswith(expected_prefix):
166
+ sub_folder = folder_path.removeprefix(f'{expected_prefix}').strip('/')#target_folder_url = folder_path.removeprefix(f'{full_path_prefix}/')
167
+ else:
168
+ # ignore full path folder which is not targeted to current drive
169
+ continue
170
+ #
171
+ files = _recurse_drive(drive_id, drive_path, sub_folder, limit_files)
156
172
  result.extend(files)
157
173
  if limit_files is not None and len(result) >= limit_files:
158
174
  return result[:limit_files]
@@ -59,6 +59,7 @@ class SlackToolkit(BaseToolkit):
59
59
  'metadata': {
60
60
  "label": "Slack",
61
61
  "icon_url": "slack-icon.svg",
62
+ "max_length": SlackToolkit.toolkit_max_length,
62
63
  "categories": ["communication"],
63
64
  "extra_categories": ["slack", "chat", "messaging", "collaboration"],
64
65
  }
@@ -34,7 +34,7 @@ class SQLToolkit(BaseToolkit):
34
34
  return create_model(
35
35
  name,
36
36
  dialect=(Literal[tuple(supported_dialects)], Field(description="Database dialect (mysql or postgres)")),
37
- database_name=(str, Field(description="Database name", json_schema_extra={'toolkit_name': True, 'max_toolkit_length': SQLToolkit.toolkit_max_length})),
37
+ database_name=(str, Field(description="Database name")),
38
38
  sql_configuration=(SqlConfiguration, Field(description="SQL Configuration", json_schema_extra={'configuration_types': ['sql']})),
39
39
  selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
40
40
  __config__=ConfigDict(json_schema_extra=
@@ -42,6 +42,7 @@ class SQLToolkit(BaseToolkit):
42
42
  'metadata':
43
43
  {
44
44
  "label": "SQL", "icon_url": "sql-icon.svg",
45
+ "max_length": SQLToolkit.toolkit_max_length,
45
46
  "categories": ["development"],
46
47
  "extra_categories": ["sql", "data management", "data analysis"]}})
47
48
  )
@@ -33,6 +33,7 @@ class TestIOToolkit(BaseToolkit):
33
33
  testio_configuration=(TestIOConfiguration, Field(description="TestIO Configuration", json_schema_extra={'configuration_types': ['testio']})),
34
34
  selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
35
35
  __config__=ConfigDict(json_schema_extra={'metadata': {"label": "TestIO", "icon_url": "testio-icon.svg",
36
+ "max_length": TOOLKIT_MAX_LENGTH,
36
37
  "categories": ["testing"],
37
38
  "extra_categories": ["test automation", "test case management", "test planning"]}})
38
39
  )
@@ -39,9 +39,6 @@ class TestrailToolkit(BaseToolkit):
39
39
  TestrailToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
40
40
  m = create_model(
41
41
  name,
42
- name=(str, Field(description="Toolkit name", json_schema_extra={
43
- 'toolkit_name': True,
44
- "max_length": TestrailToolkit.toolkit_max_length})),
45
42
  testrail_configuration=(Optional[TestRailConfiguration], Field(description="TestRail Configuration", json_schema_extra={'configuration_types': ['testrail']})),
46
43
  pgvector_configuration=(Optional[PgVectorConfiguration], Field(default = None,
47
44
  description="PgVector Configuration", json_schema_extra={'configuration_types': ['pgvector']})),
@@ -50,6 +47,7 @@ class TestrailToolkit(BaseToolkit):
50
47
  selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
51
48
  __config__=ConfigDict(json_schema_extra={'metadata':
52
49
  {"label": "Testrail", "icon_url": "testrail-icon.svg",
50
+ "max_length": TestrailToolkit.toolkit_max_length,
53
51
  "categories": ["test management"],
54
52
  "extra_categories": ["quality assurance", "test case management", "test planning"]
55
53
  }})
@@ -56,7 +56,8 @@ class XrayToolkit(BaseToolkit):
56
56
  {
57
57
  'metadata': {
58
58
  "label": "XRAY cloud", "icon_url": "xray.svg",
59
- "categories": ["test management"],
59
+ "max_length": XrayToolkit.toolkit_max_length,
60
+ "categories": ["test management"],
60
61
  "extra_categories": ["test automation", "test case management", "test planning"]
61
62
  }
62
63
  }
@@ -31,7 +31,7 @@ class ZephyrToolkit(BaseToolkit):
31
31
  ZephyrToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
32
32
  return create_model(
33
33
  name,
34
- base_url=(str, Field(description="Base URL", json_schema_extra={'toolkit_name': True, 'max_toolkit_length': ZephyrToolkit.toolkit_max_length})),
34
+ base_url=(str, Field(description="Base URL")),
35
35
  username=(str, Field(description="Username")),
36
36
  password=(SecretStr, Field(description="Password", json_schema_extra={'secret': True})),
37
37
  selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
@@ -40,6 +40,7 @@ class ZephyrToolkit(BaseToolkit):
40
40
  {
41
41
  'metadata': {
42
42
  "label": "Zephyr", "icon_url": "zephyr.svg", "hidden": True,
43
+ "max_length": ZephyrToolkit.toolkit_max_length,
43
44
  "categories": ["test management"],
44
45
  "extra_categories": ["test automation", "test case management", "test planning"]
45
46
  }}}
@@ -49,6 +49,7 @@ class ZephyrEnterpriseToolkit(BaseToolkit):
49
49
  __config__=ConfigDict(json_schema_extra={
50
50
  'metadata': {
51
51
  "label": "Zephyr Enterprise", "icon_url": "zephyr.svg",
52
+ "max_length": ZephyrEnterpriseToolkit.toolkit_max_length,
52
53
  "categories": ["test management"],
53
54
  "extra_categories": ["test automation", "test case management", "test planning"]
54
55
  }})
@@ -46,6 +46,7 @@ class ZephyrEssentialToolkit(BaseToolkit):
46
46
  # embedder settings
47
47
  embedding_model=(Optional[str], Field(default=None, description="Embedding configuration.", json_schema_extra={'configuration_model': 'embedding'})),
48
48
  __config__={'json_schema_extra': {'metadata': {"label": "Zephyr Essential", "icon_url": "zephyr.svg",
49
+ "max_length": ZephyrEssentialToolkit.toolkit_max_length,
49
50
  "categories": ["test management"],
50
51
  "extra_categories": ["test automation", "test case management", "test planning"]
51
52
  }}}
@@ -56,6 +56,7 @@ class ZephyrScaleToolkit(BaseToolkit):
56
56
  'metadata': {
57
57
  "label": "Zephyr Scale",
58
58
  "icon_url": "zephyr.svg",
59
+ "max_length": ZephyrScaleToolkit.toolkit_max_length,
59
60
  "categories": ["test management"],
60
61
  "extra_categories": ["test automation", "test case management", "test planning"],
61
62
  }
@@ -34,6 +34,7 @@ class ZephyrSquadToolkit(BaseToolkit):
34
34
  secret_key=(SecretStr, Field(description="Generated secret key", json_schema_extra={'secret': True})),
35
35
  selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
36
36
  __config__={'json_schema_extra': {'metadata': {"label": "Zephyr Squad", "icon_url": "zephyr.svg",
37
+ "max_length": ZephyrSquadToolkit.toolkit_max_length,
37
38
  "categories": ["test management"],
38
39
  "extra_categories": ["test automation", "test case management", "test planning"]
39
40
  }}}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alita_sdk
3
- Version: 0.3.449
3
+ Version: 0.3.465
4
4
  Summary: SDK for building langchain agents using resources from Alita
5
5
  Author-email: Artem Rozumenko <artyom.rozumenko@gmail.com>, Mikalai Biazruchka <mikalai_biazruchka@epam.com>, Roman Mitusov <roman_mitusov@epam.com>, Ivan Krakhmaliuk <lifedj27@gmail.com>, Artem Dubrovskiy <ad13box@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -18,7 +18,7 @@ Requires-Dist: python-dotenv~=1.0.1
18
18
  Requires-Dist: jinja2~=3.1.3
19
19
  Requires-Dist: pillow~=11.1.0
20
20
  Requires-Dist: requests~=2.3
21
- Requires-Dist: pydantic~=2.10.0
21
+ Requires-Dist: pydantic~=2.12.0
22
22
  Requires-Dist: chardet==5.2.0
23
23
  Requires-Dist: fastapi==0.115.9
24
24
  Requires-Dist: httpcore==1.0.7
@@ -144,6 +144,11 @@ Requires-Dist: pytest-cov; extra == "dev"
144
144
  Requires-Dist: black; extra == "dev"
145
145
  Requires-Dist: flake8; extra == "dev"
146
146
  Requires-Dist: mypy; extra == "dev"
147
+ Provides-Extra: cli
148
+ Requires-Dist: click>=8.1.0; extra == "cli"
149
+ Requires-Dist: rich>=13.0.0; extra == "cli"
150
+ Requires-Dist: pyyaml>=6.0; extra == "cli"
151
+ Requires-Dist: langchain-mcp-adapters; extra == "cli"
147
152
  Dynamic: license-file
148
153
 
149
154
  Alita SDK
@@ -201,6 +206,144 @@ PROJECT_ID=<your_project_id>
201
206
  NOTE: these variables can be grabbed from your Elitea platform configuration page.
202
207
  ![Platform configuration](docs/readme_imgs/platform_config.png "Platform configuration")
203
208
 
209
+ ### Custom .env File Location
210
+
211
+ By default, the CLI looks for `.env` files in the following order:
212
+ 1. `.alita/.env` (recommended)
213
+ 2. `.env` in the current directory
214
+
215
+ You can override this by setting the `ALITA_ENV_FILE` environment variable:
216
+
217
+ ```bash
218
+ export ALITA_ENV_FILE=/path/to/your/.env
219
+ alita-cli agent chat
220
+ ```
221
+
222
+ Using the CLI for Interactive Chat
223
+ ----------------------------------
224
+
225
+ The Alita SDK includes a powerful CLI for interactive agent chat sessions.
226
+
227
+ ### Starting a Chat Session
228
+
229
+ ```bash
230
+ # Interactive selection (shows all available agents + direct chat option)
231
+ alita-cli agent chat
232
+
233
+ # Chat with a specific local agent
234
+ alita-cli agent chat .alita/agents/my-agent.agent.md
235
+
236
+ # Chat with a platform agent
237
+ alita-cli agent chat my-agent-name
238
+ ```
239
+
240
+ ### Direct Chat Mode (No Agent)
241
+
242
+ You can start a chat session directly with the LLM without any agent configuration:
243
+
244
+ ```bash
245
+ alita-cli agent chat
246
+ # Select option 1: "Direct chat with model (no agent)"
247
+ ```
248
+
249
+ This is useful for quick interactions or testing without setting up an agent.
250
+
251
+ ### Chat Commands
252
+
253
+ During a chat session, you can use the following commands:
254
+
255
+ | Command | Description |
256
+ |---------|-------------|
257
+ | `/help` | Show all available commands |
258
+ | `/model` | Switch to a different model (preserves chat history) |
259
+ | `/add_mcp` | Add an MCP server from your local mcp.json (preserves chat history) |
260
+ | `/add_toolkit` | Add a toolkit from $ALITA_DIR/tools (preserves chat history) |
261
+ | `/clear` | Clear conversation history |
262
+ | `/history` | Show conversation history |
263
+ | `/save` | Save conversation to file |
264
+ | `exit` | End conversation |
265
+
266
+ ### Enhanced Input Features
267
+
268
+ The chat interface includes readline-based input enhancements:
269
+
270
+ | Feature | Key/Action |
271
+ |---------|------------|
272
+ | **Tab completion** | Press `Tab` to autocomplete commands (e.g., `/mo` → `/model`) |
273
+ | **Command history** | `↑` / `↓` arrows to navigate through previous messages |
274
+ | **Cursor movement** | `←` / `→` arrows to move within the current line |
275
+ | **Start of line** | `Ctrl+A` jumps to the beginning of the line |
276
+ | **End of line** | `Ctrl+E` jumps to the end of the line |
277
+ | **Delete word** | `Ctrl+W` deletes the word before cursor |
278
+ | **Clear line** | `Ctrl+U` clears from cursor to beginning of line |
279
+
280
+ ### Dynamic Model Switching
281
+
282
+ Use `/model` to switch models on the fly:
283
+
284
+ ```
285
+ > /model
286
+
287
+ 🔧 Select a model:
288
+
289
+ # Model Type
290
+ 1 gpt-4o openai
291
+ 2 gpt-4o-mini openai
292
+ 3 claude-3-sonnet anthropic
293
+
294
+ Select model number: 1
295
+
296
+ ✓ Selected: gpt-4o
297
+ ╭──────────────────────────────────────────────────────────────╮
298
+ │ ℹ Model switched to gpt-4o. Agent state reset, chat history │
299
+ │ preserved. │
300
+ ╰──────────────────────────────────────────────────────────────╯
301
+ ```
302
+
303
+ ### Adding MCP Servers Dynamically
304
+
305
+ Use `/add_mcp` to add MCP servers during a chat session. Servers are loaded from your local `mcp.json` file (typically at `.alita/mcp.json`):
306
+
307
+ ```
308
+ > /add_mcp
309
+
310
+ 🔌 Select an MCP server to add:
311
+
312
+ # Server Type Command/URL
313
+ 1 playwright stdio npx @playwright/mcp@latest
314
+ 2 filesystem stdio npx @anthropic/mcp-fs
315
+
316
+ Select MCP server number: 1
317
+
318
+ ✓ Selected: playwright
319
+ ╭──────────────────────────────────────────────────────────────╮
320
+ │ ℹ Added MCP: playwright. Agent state reset, chat history │
321
+ │ preserved. │
322
+ ╰──────────────────────────────────────────────────────────────╯
323
+ ```
324
+
325
+ ### Adding Toolkits Dynamically
326
+
327
+ Use `/add_toolkit` to add toolkits from your `$ALITA_DIR/tools` directory (default: `.alita/tools`):
328
+
329
+ ```
330
+ > /add_toolkit
331
+
332
+ 🧰 Select a toolkit to add:
333
+
334
+ # Toolkit Type File
335
+ 1 jira jira jira-config.json
336
+ 2 github github github-config.json
337
+
338
+ Select toolkit number: 1
339
+
340
+ ✓ Selected: jira
341
+ ╭──────────────────────────────────────────────────────────────╮
342
+ │ ℹ Added toolkit: jira. Agent state reset, chat history │
343
+ │ preserved. │
344
+ ╰──────────────────────────────────────────────────────────────╯
345
+ ```
346
+
204
347
 
205
348
 
206
349
  Using SDK with Streamlit for Local Development