codemie-test-harness 0.1.169__py3-none-any.whl → 0.1.171__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 codemie-test-harness might be problematic. Click here for more details.

@@ -0,0 +1,64 @@
1
+ """Workflow CLI commands for executing and managing workflows."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ import click
7
+
8
+ from codemie_test_harness.tests.utils.client_factory import get_client
9
+ from ..constants import CONSOLE
10
+
11
+
12
+ @click.group(name="workflow")
13
+ def workflow_cmd():
14
+ """Interact with CodeMie workflows."""
15
+ pass
16
+
17
+
18
+ @workflow_cmd.command(name="execute")
19
+ @click.option(
20
+ "--workflow-id",
21
+ required=True,
22
+ help="Workflow ID to execute",
23
+ )
24
+ @click.option(
25
+ "--user-input",
26
+ "-i",
27
+ default="",
28
+ help="User input for the workflow execution (optional)",
29
+ )
30
+ def execute_cmd(
31
+ workflow_id: str,
32
+ user_input: str,
33
+ ):
34
+ """Execute a workflow.
35
+
36
+ Example:
37
+ codemie-test-harness workflow execute --workflow-id "wf_123"
38
+ codemie-test-harness workflow execute --workflow-id "wf_123" --user-input "process this data"
39
+ """
40
+ try:
41
+ client = get_client()
42
+
43
+ CONSOLE.print(f"[yellow]Executing workflow {workflow_id}...[/yellow]")
44
+ if user_input:
45
+ CONSOLE.print(f"[blue]User input: {user_input}[/blue]")
46
+
47
+ # Execute workflow
48
+ response = client.workflows.run(workflow_id=workflow_id, user_input=user_input)
49
+
50
+ # Display response
51
+ CONSOLE.print("[green]Workflow execution started successfully![/green]")
52
+
53
+ if hasattr(response, "execution_id"):
54
+ CONSOLE.print(f"[cyan]Execution ID: {response.execution_id}[/cyan]")
55
+
56
+ if hasattr(response, "status"):
57
+ CONSOLE.print(f"[cyan]Status: {response.status}[/cyan]")
58
+
59
+ # Display the full response for debugging
60
+ CONSOLE.print(f"[dim]Response: {response}[/dim]")
61
+
62
+ except Exception as e:
63
+ CONSOLE.print(f"[red]Error executing workflow: {e}[/red]")
64
+ raise click.ClickException(str(e))
@@ -12,13 +12,16 @@ CONFIG_FILE = CONFIG_DIR / "test-harness.json"
12
12
  KEY_AUTH_SERVER_URL = "AUTH_SERVER_URL"
13
13
  KEY_AUTH_CLIENT_ID = "AUTH_CLIENT_ID"
14
14
  KEY_AUTH_CLIENT_SECRET = "AUTH_CLIENT_SECRET"
15
+ KEY_AUTH_PASSWORD = "AUTH_PASSWORD"
16
+ KEY_AUTH_USERNAME = "AUTH_USERNAME"
15
17
  KEY_AUTH_REALM_NAME = "AUTH_REALM_NAME"
16
18
  KEY_CODEMIE_API_DOMAIN = "CODEMIE_API_DOMAIN"
17
19
  KEY_MARKS = "PYTEST_MARKS"
18
20
  KEY_XDIST_N = "PYTEST_N"
19
21
  KEY_RERUNS = "PYTEST_RERUNS"
20
22
 
21
- # Integrations / external systems
23
+ # === COMPLETE INTEGRATION CREDENTIALS KEYS ===
24
+ # Version Control Systems (GitLab, GitHub)
22
25
  KEY_GIT_ENV = "GIT_ENV" # e.g. gitlab or github
23
26
  # GitLab
24
27
  KEY_GITLAB_URL = "GITLAB_URL"
@@ -29,14 +32,115 @@ KEY_GITLAB_PROJECT_ID = "GITLAB_PROJECT_ID"
29
32
  KEY_GITHUB_URL = "GITHUB_URL"
30
33
  KEY_GITHUB_TOKEN = "GITHUB_TOKEN"
31
34
  KEY_GITHUB_PROJECT = "GITHUB_PROJECT"
32
- # JIRA
35
+
36
+ # Project Management (JIRA, Confluence)
37
+ # JIRA Server
33
38
  KEY_JIRA_URL = "JIRA_URL"
34
39
  KEY_JIRA_TOKEN = "JIRA_TOKEN"
35
- KEY_JQL = "JQL"
36
- # Confluence
40
+ KEY_JQL = "JIRA_JQL"
41
+ # JIRA Cloud
42
+ KEY_JIRA_CLOUD_URL = "JIRA_CLOUD_URL"
43
+ KEY_JIRA_CLOUD_EMAIL = "JIRA_CLOUD_EMAIL"
44
+ KEY_JIRA_CLOUD_TOKEN = "JIRA_CLOUD_TOKEN"
45
+ KEY_JIRA_CLOUD_JQL = "JIRA_CLOUD_JQL"
46
+ # Confluence Server
37
47
  KEY_CONFLUENCE_URL = "CONFLUENCE_URL"
38
48
  KEY_CONFLUENCE_TOKEN = "CONFLUENCE_TOKEN"
39
- KEY_CQL = "CQL"
49
+ KEY_CQL = "CONFLUENCE_CQL"
50
+ # Confluence Cloud
51
+ KEY_CONFLUENCE_CLOUD_URL = "CONFLUENCE_CLOUD_URL"
52
+ KEY_CONFLUENCE_CLOUD_EMAIL = "CONFLUENCE_CLOUD_EMAIL"
53
+ KEY_CONFLUENCE_CLOUD_TOKEN = "CONFLUENCE_CLOUD_TOKEN"
54
+ KEY_CONFLUENCE_CLOUD_CQL = "CONFLUENCE_CLOUD_CQL"
55
+
56
+ # Cloud Providers (AWS, Azure, GCP)
57
+ # AWS
58
+ KEY_AWS_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID"
59
+ KEY_AWS_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY"
60
+ KEY_AWS_REGION = "AWS_REGION"
61
+ KEY_AWS_SESSION_TOKEN = "AWS_SESSION_TOKEN"
62
+ # Azure
63
+ KEY_AZURE_CLIENT_ID = "AZURE_CLIENT_ID"
64
+ KEY_AZURE_CLIENT_SECRET = "AZURE_CLIENT_SECRET"
65
+ KEY_AZURE_TENANT_ID = "AZURE_TENANT_ID"
66
+ KEY_AZURE_SUBSCRIPTION_ID = "AZURE_SUBSCRIPTION_ID"
67
+ # GCP
68
+ KEY_GCP_SA_KEY_BASE64 = "GCP_SA_KEY_BASE64"
69
+
70
+ # Development Tools (Azure DevOps, ServiceNow, Keycloak, SonarQube)
71
+ # Azure DevOps
72
+ KEY_AZURE_DEVOPS_URL = "AZURE_DEVOPS_URL"
73
+ KEY_AZURE_DEVOPS_TOKEN = "AZURE_DEVOPS_TOKEN"
74
+ KEY_AZURE_DEVOPS_PROJECT_NAME = "AZURE_DEVOPS_PROJECT_NAME"
75
+ KEY_AZURE_DEVOPS_ORGANIZATION_NAME = "AZURE_DEVOPS_ORGANIZATION_NAME"
76
+ # ServiceNow
77
+ KEY_SERVICENOW_URL = "SERVICENOW_URL"
78
+ KEY_SERVICENOW_TOKEN = "SERVICENOW_TOKEN"
79
+ # Keycloak
80
+ KEY_KEYCLOAK_URL = "KEYCLOAK_URL"
81
+ KEY_KEYCLOAK_REALM = "KEYCLOAK_REALM"
82
+ KEY_KEYCLOAK_CLIENT_ID = "KEYCLOAK_CLIENT_ID"
83
+ KEY_KEYCLOAK_CLIENT_SECRET = "KEYCLOAK_CLIENT_SECRET"
84
+ # SonarQube Server
85
+ KEY_SONAR_URL = "SONAR_URL"
86
+ KEY_SONAR_TOKEN = "SONAR_TOKEN"
87
+ KEY_SONAR_PROJECT_KEY = "SONAR_PROJECT_KEY"
88
+ # SonarCloud
89
+ KEY_SONAR_CLOUD_URL = "SONAR_CLOUD_URL"
90
+ KEY_SONAR_CLOUD_TOKEN = "SONAR_CLOUD_TOKEN"
91
+ KEY_SONAR_CLOUD_PROJECT_KEY = "SONAR_CLOUD_PROJECT_KEY"
92
+
93
+ # Notifications (Email/Gmail, OAuth, Telegram)
94
+ # Email/Gmail
95
+ KEY_GMAIL_URL = "GMAIL_URL"
96
+ KEY_SMTP_USERNAME = "SMTP_USERNAME"
97
+ KEY_SMTP_PASSWORD = "SMTP_PASSWORD"
98
+ # OAuth
99
+ KEY_OAUTH_URL = "OAUTH_URL"
100
+ KEY_OAUTH_CLIENT_ID = "OAUTH_CLIENT_ID"
101
+ KEY_OAUTH_CLIENT_SECRET = "OAUTH_CLIENT_SECRET"
102
+ KEY_OAUTH_REFRESH_TOKEN = "OAUTH_REFRESH_TOKEN"
103
+ # Telegram
104
+ KEY_TELEGRAM_TOKEN = "TELEGRAM_TOKEN"
105
+ KEY_TELEGRAM_CHAT_ID = "TELEGRAM_CHAT_ID"
106
+
107
+ # Research Tools (Kubernetes, Report Portal, Elasticsearch)
108
+ # Kubernetes
109
+ KEY_KUBERNETES_URL = "KUBERNETES_URL"
110
+ KEY_KUBERNETES_TOKEN = "KUBERNETES_TOKEN"
111
+ # Report Portal
112
+ KEY_REPORT_PORTAL_URL = "REPORT_PORTAL_URL"
113
+ KEY_REPORT_PORTAL_API_KEY = "REPORT_PORTAL_API_KEY"
114
+ KEY_REPORT_PORTAL_PROJECT = "REPORT_PORTAL_PROJECT"
115
+ # Elasticsearch
116
+ KEY_ELASTICSEARCH_URL = "ELASTICSEARCH_URL"
117
+ KEY_ELASTICSEARCH_API_KEY_ID = "ELASTICSEARCH_API_KEY_ID"
118
+ KEY_ELASTICSEARCH_API_KEY = "ELASTICSEARCH_API_KEY"
119
+
120
+ # Data Management (SQL databases, LiteLLM)
121
+ # LiteLLM
122
+ KEY_LITE_LLM_API_KEY = "LITE_LLM_API_KEY"
123
+ # MySQL
124
+ KEY_MYSQL_DIALECT = "MYSQL_DIALECT"
125
+ KEY_MYSQL_URL = "MYSQL_URL"
126
+ KEY_MYSQL_PORT = "MYSQL_PORT"
127
+ KEY_MYSQL_DATABASE_NAME = "MYSQL_DATABASE_NAME"
128
+ KEY_MYSQL_USERNAME = "MYSQL_USERNAME"
129
+ KEY_MYSQL_PASSWORD = "MYSQL_PASSWORD"
130
+ # PostgreSQL
131
+ KEY_POSTGRES_DIALECT = "POSTGRES_DIALECT"
132
+ KEY_POSTGRES_URL = "POSTGRES_URL"
133
+ KEY_POSTGRES_PORT = "POSTGRES_PORT"
134
+ KEY_POSTGRES_DATABASE_NAME = "POSTGRES_DATABASE_NAME"
135
+ KEY_POSTGRES_USERNAME = "POSTGRES_USERNAME"
136
+ KEY_POSTGRES_PASSWORD = "POSTGRES_PASSWORD"
137
+ # MSSQL
138
+ KEY_MSSQL_DIALECT = "MSSQL_DIALECT"
139
+ KEY_MSSQL_URL = "MSSQL_URL"
140
+ KEY_MSSQL_PORT = "MSSQL_PORT"
141
+ KEY_MSSQL_DATABASE_NAME = "MSSQL_DATABASE_NAME"
142
+ KEY_MSSQL_USERNAME = "MSSQL_USERNAME"
143
+ KEY_MSSQL_PASSWORD = "MSSQL_PASSWORD"
40
144
 
41
145
  DEFAULT_MARKS = "smoke"
42
146
  DEFAULT_XDIST_N = 8
@@ -46,11 +150,14 @@ AUTH_KEYS = [
46
150
  KEY_AUTH_SERVER_URL,
47
151
  KEY_AUTH_CLIENT_ID,
48
152
  KEY_AUTH_CLIENT_SECRET,
153
+ KEY_AUTH_USERNAME,
154
+ KEY_AUTH_PASSWORD,
49
155
  KEY_AUTH_REALM_NAME,
50
156
  KEY_CODEMIE_API_DOMAIN,
51
157
  ]
52
158
 
53
- INTEGRATION_KEYS = [
159
+ # === CREDENTIAL CATEGORIES ===
160
+ VERSION_CONTROL_KEYS = [
54
161
  KEY_GIT_ENV,
55
162
  KEY_GITLAB_URL,
56
163
  KEY_GITLAB_TOKEN,
@@ -59,10 +166,282 @@ INTEGRATION_KEYS = [
59
166
  KEY_GITHUB_URL,
60
167
  KEY_GITHUB_TOKEN,
61
168
  KEY_GITHUB_PROJECT,
169
+ ]
170
+
171
+ PROJECT_MANAGEMENT_KEYS = [
172
+ # JIRA Server
62
173
  KEY_JIRA_URL,
63
174
  KEY_JIRA_TOKEN,
64
175
  KEY_JQL,
176
+ # JIRA Cloud
177
+ KEY_JIRA_CLOUD_URL,
178
+ KEY_JIRA_CLOUD_EMAIL,
179
+ KEY_JIRA_CLOUD_TOKEN,
180
+ KEY_JIRA_CLOUD_JQL,
181
+ # Confluence Server
65
182
  KEY_CONFLUENCE_URL,
66
183
  KEY_CONFLUENCE_TOKEN,
67
184
  KEY_CQL,
185
+ # Confluence Cloud
186
+ KEY_CONFLUENCE_CLOUD_URL,
187
+ KEY_CONFLUENCE_CLOUD_EMAIL,
188
+ KEY_CONFLUENCE_CLOUD_TOKEN,
189
+ KEY_CONFLUENCE_CLOUD_CQL,
190
+ ]
191
+
192
+ CLOUD_PROVIDERS_KEYS = [
193
+ # AWS
194
+ KEY_AWS_ACCESS_KEY_ID,
195
+ KEY_AWS_SECRET_ACCESS_KEY,
196
+ KEY_AWS_REGION,
197
+ KEY_AWS_SESSION_TOKEN,
198
+ # Azure
199
+ KEY_AZURE_CLIENT_ID,
200
+ KEY_AZURE_CLIENT_SECRET,
201
+ KEY_AZURE_TENANT_ID,
202
+ KEY_AZURE_SUBSCRIPTION_ID,
203
+ # GCP
204
+ KEY_GCP_SA_KEY_BASE64,
205
+ ]
206
+
207
+ DEVELOPMENT_TOOLS_KEYS = [
208
+ # Azure DevOps
209
+ KEY_AZURE_DEVOPS_URL,
210
+ KEY_AZURE_DEVOPS_TOKEN,
211
+ KEY_AZURE_DEVOPS_PROJECT_NAME,
212
+ KEY_AZURE_DEVOPS_ORGANIZATION_NAME,
213
+ # ServiceNow
214
+ KEY_SERVICENOW_URL,
215
+ KEY_SERVICENOW_TOKEN,
216
+ # Keycloak
217
+ KEY_KEYCLOAK_URL,
218
+ KEY_KEYCLOAK_REALM,
219
+ KEY_KEYCLOAK_CLIENT_ID,
220
+ KEY_KEYCLOAK_CLIENT_SECRET,
221
+ # SonarQube Server
222
+ KEY_SONAR_URL,
223
+ KEY_SONAR_TOKEN,
224
+ KEY_SONAR_PROJECT_KEY,
225
+ # SonarCloud
226
+ KEY_SONAR_CLOUD_URL,
227
+ KEY_SONAR_CLOUD_TOKEN,
228
+ KEY_SONAR_CLOUD_PROJECT_KEY,
229
+ ]
230
+
231
+ NOTIFICATIONS_KEYS = [
232
+ # Email/Gmail
233
+ KEY_GMAIL_URL,
234
+ KEY_SMTP_USERNAME,
235
+ KEY_SMTP_PASSWORD,
236
+ # OAuth
237
+ KEY_OAUTH_URL,
238
+ KEY_OAUTH_CLIENT_ID,
239
+ KEY_OAUTH_CLIENT_SECRET,
240
+ KEY_OAUTH_REFRESH_TOKEN,
241
+ # Telegram
242
+ KEY_TELEGRAM_TOKEN,
243
+ KEY_TELEGRAM_CHAT_ID,
244
+ ]
245
+
246
+ RESEARCH_TOOLS_KEYS = [
247
+ # Kubernetes
248
+ KEY_KUBERNETES_URL,
249
+ KEY_KUBERNETES_TOKEN,
250
+ # Report Portal
251
+ KEY_REPORT_PORTAL_URL,
252
+ KEY_REPORT_PORTAL_API_KEY,
253
+ KEY_REPORT_PORTAL_PROJECT,
254
+ # Elasticsearch
255
+ KEY_ELASTICSEARCH_URL,
256
+ KEY_ELASTICSEARCH_API_KEY_ID,
257
+ KEY_ELASTICSEARCH_API_KEY,
68
258
  ]
259
+
260
+ DATA_MANAGEMENT_KEYS = [
261
+ # LiteLLM
262
+ KEY_LITE_LLM_API_KEY,
263
+ # MySQL
264
+ KEY_MYSQL_DIALECT,
265
+ KEY_MYSQL_URL,
266
+ KEY_MYSQL_PORT,
267
+ KEY_MYSQL_DATABASE_NAME,
268
+ KEY_MYSQL_USERNAME,
269
+ KEY_MYSQL_PASSWORD,
270
+ # PostgreSQL
271
+ KEY_POSTGRES_DIALECT,
272
+ KEY_POSTGRES_URL,
273
+ KEY_POSTGRES_PORT,
274
+ KEY_POSTGRES_DATABASE_NAME,
275
+ KEY_POSTGRES_USERNAME,
276
+ KEY_POSTGRES_PASSWORD,
277
+ # MSSQL
278
+ KEY_MSSQL_DIALECT,
279
+ KEY_MSSQL_URL,
280
+ KEY_MSSQL_PORT,
281
+ KEY_MSSQL_DATABASE_NAME,
282
+ KEY_MSSQL_USERNAME,
283
+ KEY_MSSQL_PASSWORD,
284
+ ]
285
+
286
+ # Combined lists for backwards compatibility
287
+ INTEGRATION_KEYS = (
288
+ VERSION_CONTROL_KEYS
289
+ + PROJECT_MANAGEMENT_KEYS
290
+ + CLOUD_PROVIDERS_KEYS
291
+ + DEVELOPMENT_TOOLS_KEYS
292
+ + NOTIFICATIONS_KEYS
293
+ + RESEARCH_TOOLS_KEYS
294
+ + DATA_MANAGEMENT_KEYS
295
+ )
296
+
297
+ # Category mapping for CLI
298
+ CREDENTIAL_CATEGORIES = {
299
+ "version-control": {
300
+ "name": "Version Control Systems",
301
+ "description": "GitLab, GitHub, and other version control platforms",
302
+ "keys": VERSION_CONTROL_KEYS,
303
+ },
304
+ "code-base": {
305
+ "name": "Code Base",
306
+ "description": "SonarQube and code analysis tools",
307
+ "keys": [
308
+ KEY_SONAR_URL,
309
+ KEY_SONAR_TOKEN,
310
+ KEY_SONAR_PROJECT_KEY,
311
+ KEY_SONAR_CLOUD_URL,
312
+ KEY_SONAR_CLOUD_TOKEN,
313
+ KEY_SONAR_CLOUD_PROJECT_KEY,
314
+ ],
315
+ },
316
+ "project-management": {
317
+ "name": "Project Management",
318
+ "description": "JIRA, Confluence, and project management tools",
319
+ "keys": PROJECT_MANAGEMENT_KEYS,
320
+ },
321
+ "cloud": {
322
+ "name": "Cloud",
323
+ "description": "AWS, GCP cloud services and Kubernetes configurations",
324
+ "keys": [
325
+ # AWS
326
+ KEY_AWS_ACCESS_KEY_ID,
327
+ KEY_AWS_SECRET_ACCESS_KEY,
328
+ KEY_AWS_REGION,
329
+ KEY_AWS_SESSION_TOKEN,
330
+ # GCP
331
+ KEY_GCP_SA_KEY_BASE64,
332
+ # Kubernetes
333
+ KEY_KUBERNETES_URL,
334
+ KEY_KUBERNETES_TOKEN,
335
+ # Azure Cloud
336
+ KEY_AZURE_CLIENT_ID,
337
+ KEY_AZURE_CLIENT_SECRET,
338
+ KEY_AZURE_TENANT_ID,
339
+ KEY_AZURE_SUBSCRIPTION_ID,
340
+ ],
341
+ },
342
+ "azure-devops": {
343
+ "name": "Azure DevOps",
344
+ "description": "Azure DevOps and Azure cloud platform services",
345
+ "keys": [
346
+ # Azure DevOps
347
+ KEY_AZURE_DEVOPS_URL,
348
+ KEY_AZURE_DEVOPS_TOKEN,
349
+ KEY_AZURE_DEVOPS_PROJECT_NAME,
350
+ KEY_AZURE_DEVOPS_ORGANIZATION_NAME,
351
+ ],
352
+ },
353
+ "access-management": {
354
+ "name": "Access Management",
355
+ "description": "Keycloak and identity management systems",
356
+ "keys": [
357
+ KEY_KEYCLOAK_URL,
358
+ KEY_KEYCLOAK_REALM,
359
+ KEY_KEYCLOAK_CLIENT_ID,
360
+ KEY_KEYCLOAK_CLIENT_SECRET,
361
+ ],
362
+ },
363
+ "notification-systems": {
364
+ "name": "Notification Systems",
365
+ "description": "Email, OAuth, Telegram, and communication platforms",
366
+ "keys": NOTIFICATIONS_KEYS,
367
+ },
368
+ "data-management": {
369
+ "name": "Data Management",
370
+ "description": "SQL databases, Elasticsearch, and data storage systems",
371
+ "keys": DATA_MANAGEMENT_KEYS
372
+ + [
373
+ KEY_ELASTICSEARCH_URL,
374
+ KEY_ELASTICSEARCH_API_KEY_ID,
375
+ KEY_ELASTICSEARCH_API_KEY,
376
+ ],
377
+ },
378
+ "it-service-management": {
379
+ "name": "IT Service Management",
380
+ "description": "ServiceNow and IT service management platforms",
381
+ "keys": [
382
+ KEY_SERVICENOW_URL,
383
+ KEY_SERVICENOW_TOKEN,
384
+ ],
385
+ },
386
+ "quality-assurance": {
387
+ "name": "Quality Assurance",
388
+ "description": "Report Portal and quality assurance tools",
389
+ "keys": [
390
+ KEY_REPORT_PORTAL_URL,
391
+ KEY_REPORT_PORTAL_API_KEY,
392
+ KEY_REPORT_PORTAL_PROJECT,
393
+ ],
394
+ },
395
+ }
396
+
397
+ # Sensitive fields that should be masked in input/output
398
+ SENSITIVE_KEYS = {
399
+ KEY_AUTH_CLIENT_SECRET,
400
+ KEY_AUTH_PASSWORD,
401
+ KEY_GITLAB_TOKEN,
402
+ KEY_GITHUB_TOKEN,
403
+ KEY_JIRA_TOKEN,
404
+ KEY_JIRA_CLOUD_TOKEN,
405
+ KEY_CONFLUENCE_TOKEN,
406
+ KEY_CONFLUENCE_CLOUD_TOKEN,
407
+ KEY_AWS_SECRET_ACCESS_KEY,
408
+ KEY_AWS_SESSION_TOKEN,
409
+ KEY_AZURE_CLIENT_SECRET,
410
+ KEY_GCP_SA_KEY_BASE64,
411
+ KEY_AZURE_DEVOPS_TOKEN,
412
+ KEY_SERVICENOW_TOKEN,
413
+ KEY_KEYCLOAK_CLIENT_SECRET,
414
+ KEY_SONAR_TOKEN,
415
+ KEY_SONAR_CLOUD_TOKEN,
416
+ KEY_SMTP_PASSWORD,
417
+ KEY_OAUTH_CLIENT_SECRET,
418
+ KEY_OAUTH_REFRESH_TOKEN,
419
+ KEY_TELEGRAM_TOKEN,
420
+ KEY_KUBERNETES_TOKEN,
421
+ KEY_REPORT_PORTAL_API_KEY,
422
+ KEY_ELASTICSEARCH_API_KEY,
423
+ KEY_LITE_LLM_API_KEY,
424
+ KEY_MYSQL_PASSWORD,
425
+ KEY_POSTGRES_PASSWORD,
426
+ KEY_MSSQL_PASSWORD,
427
+ }
428
+
429
+
430
+ def is_sensitive_key(key: str) -> bool:
431
+ """Check if a credential key contains sensitive information."""
432
+ return key in SENSITIVE_KEYS
433
+
434
+
435
+ def mask_sensitive_value(value: str, show_real: bool = False) -> str:
436
+ """Mask sensitive credential values for display.
437
+
438
+ Args:
439
+ value: The value to potentially mask
440
+ show_real: If True, return the real value instead of masking
441
+ """
442
+ if show_real:
443
+ return value
444
+
445
+ if not value or len(value) < 4:
446
+ return "*" * len(value) if value else ""
447
+ return value[:2] + "*" * (len(value) - 4) + value[-2:]
@@ -43,3 +43,12 @@ def ensure_env_from_config(keys: list[str]) -> None:
43
43
  for k in keys:
44
44
  if k not in os.environ and k in cfg:
45
45
  os.environ[k] = str(cfg[k])
46
+
47
+
48
+ def unset_config_key(key: str) -> bool:
49
+ cfg = load_config()
50
+ if key in cfg:
51
+ del cfg[key]
52
+ save_config(cfg)
53
+ return True
54
+ return False
@@ -14,6 +14,9 @@ from codemie_sdk.models.assistant import (
14
14
  ChatRole,
15
15
  )
16
16
  from codemie_test_harness.tests import TEST_USER, PROJECT, LANGFUSE_TRACES_ENABLED
17
+ from codemie_test_harness.tests.test_data.assistant_test_data import (
18
+ EXCEL_TOOL_TEST_DATA,
19
+ )
17
20
  from codemie_test_harness.tests.test_data.file_test_data import (
18
21
  files_with_different_types_test_data,
19
22
  file_test_data,
@@ -390,3 +393,42 @@ def test_create_assistant_and_prompt_with_multiple_files(
390
393
  assistant, prompt, conversation_id=conversation_id
391
394
  )
392
395
  similarity_check.check_similarity(response, RESPONSE_FOR_TWO_FILES_UPLOADED)
396
+
397
+
398
+ @pytest.mark.assistant
399
+ @pytest.mark.file
400
+ @pytest.mark.regression
401
+ @pytest.mark.smoke
402
+ @pytest.mark.parametrize("prompt,expected_response", EXCEL_TOOL_TEST_DATA)
403
+ def test_excel_tool_extended_functionality(
404
+ assistant_utils, assistant, similarity_check, prompt, expected_response
405
+ ):
406
+ """
407
+ Test extended Excel tool functionality with various scenarios.
408
+
409
+ This test covers:
410
+ - Data extraction from visible sheets only
411
+ - All data including hidden sheets
412
+ - Sheet name listing functionality
413
+ - File statistics and structure analysis
414
+ - Single sheet extraction by index and name
415
+ - Data cleaning and normalization
416
+ - Hidden sheet visibility control
417
+ - Column structure and data type analysis
418
+ - Tabular structure normalization
419
+ - Multi-sheet comprehensive analysis
420
+
421
+ """
422
+ assistant_instance = assistant()
423
+
424
+ uploaded_file = assistant_utils.upload_file_to_chat(
425
+ FILES_PATH / "test_extended.xlsx"
426
+ )
427
+ file_url = uploaded_file.get("file_url")
428
+
429
+ # Send the prompt with the uploaded file
430
+ response = assistant_utils.ask_assistant(
431
+ assistant_instance, prompt, file_urls=[file_url]
432
+ )
433
+
434
+ similarity_check.check_similarity(response, expected_response)