mcli-framework 7.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mcli-framework might be problematic. Click here for more details.

Files changed (186) hide show
  1. mcli/app/chat_cmd.py +42 -0
  2. mcli/app/commands_cmd.py +226 -0
  3. mcli/app/completion_cmd.py +216 -0
  4. mcli/app/completion_helpers.py +288 -0
  5. mcli/app/cron_test_cmd.py +697 -0
  6. mcli/app/logs_cmd.py +419 -0
  7. mcli/app/main.py +492 -0
  8. mcli/app/model/model.py +1060 -0
  9. mcli/app/model_cmd.py +227 -0
  10. mcli/app/redis_cmd.py +269 -0
  11. mcli/app/video/video.py +1114 -0
  12. mcli/app/visual_cmd.py +303 -0
  13. mcli/chat/chat.py +2409 -0
  14. mcli/chat/command_rag.py +514 -0
  15. mcli/chat/enhanced_chat.py +652 -0
  16. mcli/chat/system_controller.py +1010 -0
  17. mcli/chat/system_integration.py +1016 -0
  18. mcli/cli.py +25 -0
  19. mcli/config.toml +20 -0
  20. mcli/lib/api/api.py +586 -0
  21. mcli/lib/api/daemon_client.py +203 -0
  22. mcli/lib/api/daemon_client_local.py +44 -0
  23. mcli/lib/api/daemon_decorator.py +217 -0
  24. mcli/lib/api/mcli_decorators.py +1032 -0
  25. mcli/lib/auth/auth.py +85 -0
  26. mcli/lib/auth/aws_manager.py +85 -0
  27. mcli/lib/auth/azure_manager.py +91 -0
  28. mcli/lib/auth/credential_manager.py +192 -0
  29. mcli/lib/auth/gcp_manager.py +93 -0
  30. mcli/lib/auth/key_manager.py +117 -0
  31. mcli/lib/auth/mcli_manager.py +93 -0
  32. mcli/lib/auth/token_manager.py +75 -0
  33. mcli/lib/auth/token_util.py +1011 -0
  34. mcli/lib/config/config.py +47 -0
  35. mcli/lib/discovery/__init__.py +1 -0
  36. mcli/lib/discovery/command_discovery.py +274 -0
  37. mcli/lib/erd/erd.py +1345 -0
  38. mcli/lib/erd/generate_graph.py +453 -0
  39. mcli/lib/files/files.py +76 -0
  40. mcli/lib/fs/fs.py +109 -0
  41. mcli/lib/lib.py +29 -0
  42. mcli/lib/logger/logger.py +611 -0
  43. mcli/lib/performance/optimizer.py +409 -0
  44. mcli/lib/performance/rust_bridge.py +502 -0
  45. mcli/lib/performance/uvloop_config.py +154 -0
  46. mcli/lib/pickles/pickles.py +50 -0
  47. mcli/lib/search/cached_vectorizer.py +479 -0
  48. mcli/lib/services/data_pipeline.py +460 -0
  49. mcli/lib/services/lsh_client.py +441 -0
  50. mcli/lib/services/redis_service.py +387 -0
  51. mcli/lib/shell/shell.py +137 -0
  52. mcli/lib/toml/toml.py +33 -0
  53. mcli/lib/ui/styling.py +47 -0
  54. mcli/lib/ui/visual_effects.py +634 -0
  55. mcli/lib/watcher/watcher.py +185 -0
  56. mcli/ml/api/app.py +215 -0
  57. mcli/ml/api/middleware.py +224 -0
  58. mcli/ml/api/routers/admin_router.py +12 -0
  59. mcli/ml/api/routers/auth_router.py +244 -0
  60. mcli/ml/api/routers/backtest_router.py +12 -0
  61. mcli/ml/api/routers/data_router.py +12 -0
  62. mcli/ml/api/routers/model_router.py +302 -0
  63. mcli/ml/api/routers/monitoring_router.py +12 -0
  64. mcli/ml/api/routers/portfolio_router.py +12 -0
  65. mcli/ml/api/routers/prediction_router.py +267 -0
  66. mcli/ml/api/routers/trade_router.py +12 -0
  67. mcli/ml/api/routers/websocket_router.py +76 -0
  68. mcli/ml/api/schemas.py +64 -0
  69. mcli/ml/auth/auth_manager.py +425 -0
  70. mcli/ml/auth/models.py +154 -0
  71. mcli/ml/auth/permissions.py +302 -0
  72. mcli/ml/backtesting/backtest_engine.py +502 -0
  73. mcli/ml/backtesting/performance_metrics.py +393 -0
  74. mcli/ml/cache.py +400 -0
  75. mcli/ml/cli/main.py +398 -0
  76. mcli/ml/config/settings.py +394 -0
  77. mcli/ml/configs/dvc_config.py +230 -0
  78. mcli/ml/configs/mlflow_config.py +131 -0
  79. mcli/ml/configs/mlops_manager.py +293 -0
  80. mcli/ml/dashboard/app.py +532 -0
  81. mcli/ml/dashboard/app_integrated.py +738 -0
  82. mcli/ml/dashboard/app_supabase.py +560 -0
  83. mcli/ml/dashboard/app_training.py +615 -0
  84. mcli/ml/dashboard/cli.py +51 -0
  85. mcli/ml/data_ingestion/api_connectors.py +501 -0
  86. mcli/ml/data_ingestion/data_pipeline.py +567 -0
  87. mcli/ml/data_ingestion/stream_processor.py +512 -0
  88. mcli/ml/database/migrations/env.py +94 -0
  89. mcli/ml/database/models.py +667 -0
  90. mcli/ml/database/session.py +200 -0
  91. mcli/ml/experimentation/ab_testing.py +845 -0
  92. mcli/ml/features/ensemble_features.py +607 -0
  93. mcli/ml/features/political_features.py +676 -0
  94. mcli/ml/features/recommendation_engine.py +809 -0
  95. mcli/ml/features/stock_features.py +573 -0
  96. mcli/ml/features/test_feature_engineering.py +346 -0
  97. mcli/ml/logging.py +85 -0
  98. mcli/ml/mlops/data_versioning.py +518 -0
  99. mcli/ml/mlops/experiment_tracker.py +377 -0
  100. mcli/ml/mlops/model_serving.py +481 -0
  101. mcli/ml/mlops/pipeline_orchestrator.py +614 -0
  102. mcli/ml/models/base_models.py +324 -0
  103. mcli/ml/models/ensemble_models.py +675 -0
  104. mcli/ml/models/recommendation_models.py +474 -0
  105. mcli/ml/models/test_models.py +487 -0
  106. mcli/ml/monitoring/drift_detection.py +676 -0
  107. mcli/ml/monitoring/metrics.py +45 -0
  108. mcli/ml/optimization/portfolio_optimizer.py +834 -0
  109. mcli/ml/preprocessing/data_cleaners.py +451 -0
  110. mcli/ml/preprocessing/feature_extractors.py +491 -0
  111. mcli/ml/preprocessing/ml_pipeline.py +382 -0
  112. mcli/ml/preprocessing/politician_trading_preprocessor.py +569 -0
  113. mcli/ml/preprocessing/test_preprocessing.py +294 -0
  114. mcli/ml/scripts/populate_sample_data.py +200 -0
  115. mcli/ml/tasks.py +400 -0
  116. mcli/ml/tests/test_integration.py +429 -0
  117. mcli/ml/tests/test_training_dashboard.py +387 -0
  118. mcli/public/oi/oi.py +15 -0
  119. mcli/public/public.py +4 -0
  120. mcli/self/self_cmd.py +1246 -0
  121. mcli/workflow/daemon/api_daemon.py +800 -0
  122. mcli/workflow/daemon/async_command_database.py +681 -0
  123. mcli/workflow/daemon/async_process_manager.py +591 -0
  124. mcli/workflow/daemon/client.py +530 -0
  125. mcli/workflow/daemon/commands.py +1196 -0
  126. mcli/workflow/daemon/daemon.py +905 -0
  127. mcli/workflow/daemon/daemon_api.py +59 -0
  128. mcli/workflow/daemon/enhanced_daemon.py +571 -0
  129. mcli/workflow/daemon/process_cli.py +244 -0
  130. mcli/workflow/daemon/process_manager.py +439 -0
  131. mcli/workflow/daemon/test_daemon.py +275 -0
  132. mcli/workflow/dashboard/dashboard_cmd.py +113 -0
  133. mcli/workflow/docker/docker.py +0 -0
  134. mcli/workflow/file/file.py +100 -0
  135. mcli/workflow/gcloud/config.toml +21 -0
  136. mcli/workflow/gcloud/gcloud.py +58 -0
  137. mcli/workflow/git_commit/ai_service.py +328 -0
  138. mcli/workflow/git_commit/commands.py +430 -0
  139. mcli/workflow/lsh_integration.py +355 -0
  140. mcli/workflow/model_service/client.py +594 -0
  141. mcli/workflow/model_service/download_and_run_efficient_models.py +288 -0
  142. mcli/workflow/model_service/lightweight_embedder.py +397 -0
  143. mcli/workflow/model_service/lightweight_model_server.py +714 -0
  144. mcli/workflow/model_service/lightweight_test.py +241 -0
  145. mcli/workflow/model_service/model_service.py +1955 -0
  146. mcli/workflow/model_service/ollama_efficient_runner.py +425 -0
  147. mcli/workflow/model_service/pdf_processor.py +386 -0
  148. mcli/workflow/model_service/test_efficient_runner.py +234 -0
  149. mcli/workflow/model_service/test_example.py +315 -0
  150. mcli/workflow/model_service/test_integration.py +131 -0
  151. mcli/workflow/model_service/test_new_features.py +149 -0
  152. mcli/workflow/openai/openai.py +99 -0
  153. mcli/workflow/politician_trading/commands.py +1790 -0
  154. mcli/workflow/politician_trading/config.py +134 -0
  155. mcli/workflow/politician_trading/connectivity.py +490 -0
  156. mcli/workflow/politician_trading/data_sources.py +395 -0
  157. mcli/workflow/politician_trading/database.py +410 -0
  158. mcli/workflow/politician_trading/demo.py +248 -0
  159. mcli/workflow/politician_trading/models.py +165 -0
  160. mcli/workflow/politician_trading/monitoring.py +413 -0
  161. mcli/workflow/politician_trading/scrapers.py +966 -0
  162. mcli/workflow/politician_trading/scrapers_california.py +412 -0
  163. mcli/workflow/politician_trading/scrapers_eu.py +377 -0
  164. mcli/workflow/politician_trading/scrapers_uk.py +350 -0
  165. mcli/workflow/politician_trading/scrapers_us_states.py +438 -0
  166. mcli/workflow/politician_trading/supabase_functions.py +354 -0
  167. mcli/workflow/politician_trading/workflow.py +852 -0
  168. mcli/workflow/registry/registry.py +180 -0
  169. mcli/workflow/repo/repo.py +223 -0
  170. mcli/workflow/scheduler/commands.py +493 -0
  171. mcli/workflow/scheduler/cron_parser.py +238 -0
  172. mcli/workflow/scheduler/job.py +182 -0
  173. mcli/workflow/scheduler/monitor.py +139 -0
  174. mcli/workflow/scheduler/persistence.py +324 -0
  175. mcli/workflow/scheduler/scheduler.py +679 -0
  176. mcli/workflow/sync/sync_cmd.py +437 -0
  177. mcli/workflow/sync/test_cmd.py +314 -0
  178. mcli/workflow/videos/videos.py +242 -0
  179. mcli/workflow/wakatime/wakatime.py +11 -0
  180. mcli/workflow/workflow.py +37 -0
  181. mcli_framework-7.0.0.dist-info/METADATA +479 -0
  182. mcli_framework-7.0.0.dist-info/RECORD +186 -0
  183. mcli_framework-7.0.0.dist-info/WHEEL +5 -0
  184. mcli_framework-7.0.0.dist-info/entry_points.txt +7 -0
  185. mcli_framework-7.0.0.dist-info/licenses/LICENSE +21 -0
  186. mcli_framework-7.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,180 @@
1
+ import warnings
2
+
3
+ import click
4
+ import requests
5
+
6
+ # Suppress the warning about python-Levenshtein
7
+ warnings.filterwarnings("ignore", message="Using slow pure-python SequenceMatcher")
8
+ from fuzzywuzzy import process
9
+
10
+ """_summary_
11
+ ssh -o GatewayPorts=yes -o ServerAliveInterval=60 -o ProxyCommand="ssh -W %h:%p myuser@my-proxy-server" -L80::80 -L443::443 myuser@localhost
12
+ Returns:
13
+ _type_: _description_
14
+ """
15
+
16
+
17
+ class DockerClient:
18
+ def __init__(self, registry_url):
19
+ self.registry_url = registry_url
20
+
21
+ def _make_request(self, endpoint):
22
+ url = f"{self.registry_url}/{endpoint}"
23
+ try:
24
+ response = requests.get(url)
25
+ response.raise_for_status()
26
+ return response.json()
27
+ except requests.exceptions.RequestException as e:
28
+ logger.info(f"Error fetching data from {url}: {e}")
29
+ return None
30
+
31
+ def get_catalog(self):
32
+ return self._make_request("v2/_catalog")
33
+
34
+ def get_tags(self, repository):
35
+ return self._make_request(f"v2/{repository}/tags/list")
36
+
37
+ def search_repository(self, repository):
38
+ catalog = self.get_catalog()
39
+ if catalog:
40
+ return [repo for repo in catalog.get("repositories", []) if repository in repo]
41
+ return []
42
+
43
+ def search_all_repositories(self, token: str):
44
+ logger.info("search_all_repositories")
45
+ catalog = self.get_catalog()
46
+ response = []
47
+ for repo in catalog.get("repositories", []):
48
+ try:
49
+ tags = self.get_tags(repository=repo).get("tags", [])
50
+ query_results = process.extract(token, tags, limit=2)
51
+ matching_tuples = [
52
+ (version, score) for version, score in query_results if score > 88
53
+ ]
54
+ if len(matching_tuples) > 0:
55
+ response.append(f"{repo}: {matching_tuples}")
56
+ logger.info(f"{repo}: {matching_tuples}")
57
+ except Exception as e:
58
+ logger.info(e)
59
+ pass
60
+ return response
61
+
62
+ def count_images(self, repository):
63
+ tags = self.get_tags(repository)
64
+ if tags:
65
+ return len(tags.get("tags", []))
66
+ return 0
67
+
68
+
69
+ @click.group()
70
+ @click.option(
71
+ "--registry-url",
72
+ default="",
73
+ help="URL of the Docker registry",
74
+ )
75
+ @click.pass_context
76
+ def registry(ctx, registry_url):
77
+ """registry utility - use this to interact with the mcli Docker registry."""
78
+ ctx.obj = DockerClient(registry_url)
79
+
80
+
81
+ @registry.command()
82
+ @click.pass_context
83
+ def catalog(ctx):
84
+ """Fetch the catalog of repositories."""
85
+ client = ctx.obj
86
+ catalog = client.get_catalog()
87
+ if catalog:
88
+ click.echo("Catalog:")
89
+ for repo in catalog.get("repositories", []):
90
+ click.echo(f" - {repo}")
91
+
92
+
93
+ @registry.command()
94
+ @click.argument("repository")
95
+ @click.option("--tag-name")
96
+ @click.pass_context
97
+ def tags(ctx, repository, tag_name):
98
+ """Fetch the tags for a given repository."""
99
+ client = ctx.obj
100
+ tags = client.get_tags(repository)
101
+ if tag_name:
102
+ logger.info(tag_name)
103
+ else:
104
+ click.echo(f"Tags for repository '{repository}':")
105
+ for tag in tags.get("tags", []):
106
+ click.echo(f" - {tag}")
107
+
108
+
109
+ @registry.command(name="search-tags")
110
+ @click.argument("repository")
111
+ @click.option("--tag-name")
112
+ @click.pass_context
113
+ def search_tags(ctx, repository, tag_name):
114
+ """Fetch the tags for a given repository."""
115
+ client = ctx.obj
116
+ tags = client.get_tags(repository)
117
+ if tag_name:
118
+ logger.info(tag_name)
119
+ else:
120
+ click.echo(f"Tags for repository '{repository}':")
121
+ for tag in tags.get("tags", []):
122
+ click.echo(f" - {tag}")
123
+
124
+
125
+ @registry.command()
126
+ @click.argument("repository")
127
+ @click.pass_context
128
+ def search(ctx, repository):
129
+ """Search for a repository by name."""
130
+ client = ctx.obj
131
+ results = client.search_repository(repository)
132
+ if results:
133
+ click.echo(f"Search results for '{repository}':")
134
+ for repo in results:
135
+ click.echo(f" - {repo}")
136
+
137
+
138
+ @registry.command()
139
+ @click.argument("repository")
140
+ @click.argument("tag")
141
+ @click.pass_context
142
+ def image_info(ctx, repository, tag):
143
+ """Get detailed information about a specific image."""
144
+ client = ctx.obj
145
+ info = client.get_image_info(repository, tag)
146
+ if info:
147
+ click.echo(f"Image info for {repository}:{tag}:")
148
+ click.echo(info)
149
+
150
+
151
+ @registry.command()
152
+ @click.argument("repository")
153
+ @click.pass_context
154
+ def count(ctx, repository):
155
+ """Count the number of tags/images in a repository."""
156
+ client = ctx.obj
157
+ count = client.count_images(repository)
158
+ click.echo(f"Number of tags in repository '{repository}': {count}")
159
+
160
+
161
+ @registry.command()
162
+ @click.argument("repository")
163
+ @click.argument("tag")
164
+ @click.pass_context
165
+ def pull(ctx, repository, tag):
166
+ """Pull an image from the registry."""
167
+ client = ctx.obj
168
+ image = client.pull_image(repository, tag)
169
+ if image:
170
+ click.echo(f"Pulled image {repository}:{tag}")
171
+
172
+
173
+ # TODO: Implement the pull_image method in DockerClient
174
+
175
+
176
+ @registry.command("fuzzy-search")
177
+ @click.argument("token")
178
+ @click.pass_context
179
+ def fuzzy_search(ctx, token):
180
+ return ctx.obj.search_all_repositories(token)
@@ -0,0 +1,223 @@
1
+ import csv
2
+ import os
3
+
4
+ import click
5
+ import pandas as pd
6
+ from openai import OpenAI
7
+ from openpyxl.styles import Alignment
8
+
9
+ from mcli.lib.logger.logger import get_logger
10
+ from mcli.lib.shell.shell import get_shell_script_path, shell_exec
11
+
12
+ logger = get_logger(__name__)
13
+
14
+
15
+ @click.group(name="repo")
16
+ def repo():
17
+ """repo utility - use this to interact with git and relevant utilities"""
18
+ click.echo("repo")
19
+
20
+
21
+ @repo.command()
22
+ @click.argument("path")
23
+ def analyze(path: str):
24
+ """Provides a source lines of code analysis for a given pkg path"""
25
+ _analyze(path)
26
+
27
+
28
+ def _analyze(path: str):
29
+ # Define the directory to analyze
30
+ repo_directory = path
31
+
32
+ # Define the file extensions to count
33
+ file_extensions = {
34
+ "Java": ".java",
35
+ "Python": ".py",
36
+ "js": ".js",
37
+ "HTML": ".html",
38
+ "mcli": ".mcli",
39
+ "ts": ".ts",
40
+ "tsx": ".tsx",
41
+ "JSON": ".json",
42
+ "scss": ".scss",
43
+ }
44
+
45
+ # Define the files and extensions to exclude
46
+ exclude_files = [
47
+ "node_modules",
48
+ "resources",
49
+ "provision",
50
+ "jenkins",
51
+ "git_hooks",
52
+ "deps",
53
+ "submodules",
54
+ ]
55
+
56
+ exclude_extensions = [".log", ".tmp", ".md", ".yml", ".sh", ".txt"]
57
+
58
+ # Function to apply formatting to Excel sheets
59
+ def format_excel_sheets(writer, sheet_name):
60
+ workbook = writer.book
61
+ worksheet = workbook[sheet_name]
62
+ for col in worksheet.columns:
63
+ max_length = 0
64
+ column = col[0].column_letter # Get the column name
65
+ for cell in col:
66
+ try:
67
+ if len(str(cell.value)) > max_length:
68
+ max_length = len(cell.value)
69
+ except Exception as e:
70
+ logger.info(e)
71
+ pass
72
+ adjusted_width = max_length + 2
73
+ worksheet.column_dimensions[column].width = adjusted_width
74
+ for cell in col:
75
+ cell.alignment = Alignment(wrap_text=True)
76
+
77
+ # Function to count files and lines of code for a given directory
78
+ def count_files_and_sloc(directory, extensions, exclude_files, exclude_extensions):
79
+ sloc_count = {ext: {"files": 0, "sloc": 0, "details": []} for ext in extensions}
80
+ for root, dirs, files in os.walk(directory):
81
+ # Exclude specified directories
82
+ dirs[:] = [d for d in dirs if d not in exclude_files]
83
+ for file in files:
84
+ # Exclude specified files and extensions
85
+ if any(file.endswith(ext) for ext in exclude_extensions) or file in exclude_files:
86
+ continue
87
+ for ext, ext_name in extensions.items():
88
+ if file.endswith(ext_name):
89
+ sloc_count[ext]["files"] += 1
90
+ file_path = os.path.join(root, file)
91
+ with open(file_path, "r", errors="ignore") as f:
92
+ sloc = sum(1 for line in f if line.strip() and line.strip() != "\n")
93
+ sloc_count[ext]["sloc"] += sloc
94
+ sloc_count[ext]["details"].append(
95
+ {"filename": file, "filepath": file_path, "sloc": sloc}
96
+ )
97
+ return sloc_count
98
+
99
+ # Function to write results to CSV and Excel files
100
+ def write_results_to_files(sloc_counts, csv_file, excel_file):
101
+ summary_data = []
102
+ # Write the results to a CSV file
103
+ with open(csv_file, mode="w", newline="") as file:
104
+ writer = csv.writer(file)
105
+ writer.writerow(["File Type", "Number of Files", "SLOC"])
106
+ for ext, counts in sloc_counts.items():
107
+ writer.writerow([ext, counts["files"], counts["sloc"]])
108
+ summary_data.append([ext, counts["files"], counts["sloc"]])
109
+
110
+ # Write the detailed results to an Excel file
111
+ with pd.ExcelWriter(excel_file, engine="openpyxl") as writer:
112
+ # Write summary as the first sheet
113
+ df_summary = pd.DataFrame(
114
+ summary_data, columns=["File Type", "Number of Files", "SLOC"]
115
+ )
116
+ df_summary.to_excel(writer, sheet_name="Summary", index=False)
117
+ format_excel_sheets(writer, "Summary")
118
+
119
+ # Write details for each file type
120
+ for ext, counts in sloc_counts.items():
121
+ df = pd.DataFrame(counts["details"])
122
+ df.to_excel(writer, sheet_name=ext, index=False)
123
+ format_excel_sheets(writer, ext)
124
+
125
+ logger.info(f"\nResults have been written to {csv_file} and {excel_file}")
126
+
127
+ # Generate the SLOC counts
128
+ sloc_counts = count_files_and_sloc(
129
+ repo_directory, file_extensions, exclude_files, exclude_extensions
130
+ )
131
+
132
+ # logger.info the results in a tabular format
133
+ logger.info("Source Lines of Code (SLOC)")
134
+ logger.info("-" * 50)
135
+ logger.info(f"{'File Type':<10}{'Number of Files':<20}{'SLOC':<10}")
136
+ logger.info("-" * 50)
137
+ for ext, counts in sloc_counts.items():
138
+ logger.info(f"{ext:<10}{counts['files']:<20}{counts['sloc']:<10}")
139
+
140
+ # Define the output file names
141
+ csv_file = "sloc_report.csv"
142
+ excel_file = "sloc_report.xlsx"
143
+
144
+ # Write the results to CSV and Excel files
145
+ write_results_to_files(sloc_counts, csv_file, excel_file)
146
+
147
+
148
+ @repo.command(name="wt")
149
+ def worktree():
150
+ """Create and manage worktrees"""
151
+ scripts_path = get_shell_script_path("repo", __file__)
152
+ shell_exec(scripts_path, "wt")
153
+
154
+
155
+ @repo.command(name="commit")
156
+ def commit():
157
+ """Edit commits to a repository"""
158
+ click.echo("commit")
159
+
160
+
161
+ @repo.command(name="revert")
162
+ def revert():
163
+ """Create and manage worktrees"""
164
+ scripts_path = get_shell_script_path("repo", __file__)
165
+ shell_exec(scripts_path, "revert")
166
+
167
+
168
+ @repo.command(name="migration-loe")
169
+ @click.argument("branch-a")
170
+ @click.argument("branch-b")
171
+ def loe(branch_a: str, branch_b: str):
172
+ """Create and manage worktrees"""
173
+ scripts_path = get_shell_script_path("repo", __file__)
174
+ result = shell_exec(scripts_path, "migration_loe", branch_a, branch_b)
175
+ # Assume result['result'] contains the output from the shell script
176
+ if result is None:
177
+ return
178
+ # Extract the list of files from the result
179
+ logger.info(result)
180
+ return
181
+ file_list = result.get("result", [])
182
+
183
+ # Format the file list as a string for the prompt
184
+ file_summary = "\n".join(file_list)
185
+
186
+ # Construct the prompt for GPT-4
187
+ prompt = f"""
188
+ You are an expert in planning engineering projects, estimating level of effort, and a granular approach to changes for each item in an enmerated list. Analyze the following list of files to categorize the changes (e.g., UI updates, backend changes, configuration edits) and provide a detailed summary for a migration effort. Enumerate the changes in each file. Your output should also include a suggested categorization of the changes such that they can be used by the migration team to create issues in jira and track progress. The categorization must include every single file provided and report each one of them back in a category.
189
+
190
+ {file_summary}
191
+ """
192
+
193
+ try:
194
+ # Initialize the OpenAI client - API key from environment
195
+ api_key = os.getenv("OPENAI_API_KEY")
196
+ if not api_key:
197
+ logger.error("OPENAI_API_KEY environment variable not set")
198
+ return
199
+
200
+ client = OpenAI(api_key=api_key)
201
+
202
+ # Call the GPT-4 model using the client
203
+ chat_completion = client.chat.completions.create(
204
+ messages=[
205
+ {
206
+ "role": "user",
207
+ "content": prompt,
208
+ }
209
+ ],
210
+ model="gpt-4",
211
+ )
212
+
213
+ # Access the response content correctly
214
+ analysis = chat_completion.choices[0].message.content
215
+ logger.info("Analysis of changes:")
216
+ logger.info(analysis)
217
+
218
+ except Exception as e:
219
+ logger.info(f"An error occurred while calling OpenAI API: {e}")
220
+
221
+
222
+ if __name__ == "__main__":
223
+ repo()