agi-gui 0.0.1__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.
agi_gui/AGILAB.py ADDED
@@ -0,0 +1,220 @@
1
+ # BSD 3-Clause License
2
+ #
3
+ # Copyright (c) 2025, Jean-Pierre Morard, THALES SIX GTS France SAS
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9
+ # 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10
+ # 3. Neither the name of Jean-Pierre Morard nor the names of its contributors, or THALES SIX GTS France SAS, may be used to endorse or promote products derived from this software without specific prior written permission.
11
+ #
12
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13
+
14
+ from pathlib import Path
15
+ from datetime import datetime
16
+ import streamlit as st
17
+ import importlib
18
+ import base64
19
+ import sys
20
+ import os
21
+ import argparse
22
+
23
+ # -------------------- Import Statements -------------------- #
24
+ # (Include any other necessary imports from your original code)
25
+ from agi_gui.pagelib import env, get_about_content, render_logo, open_docs, RESOURCE_PATH, get_base64_of_image
26
+
27
+ # -------------------- Additional Imports -------------------- #
28
+ import ast
29
+ import re
30
+ import json
31
+ import glob
32
+ from pathlib import Path, PurePosixPath, PureWindowsPath
33
+ from functools import lru_cache
34
+ import pandas as pd
35
+ import toml
36
+ import io
37
+ import subprocess
38
+ import random
39
+ import socket
40
+ from PIL import Image
41
+ import base64
42
+ import runpy
43
+ from typing import List, Union, Optional, Dict
44
+
45
+
46
+ # -------------------- Helper Functions -------------------- #
47
+ def load_file_content(file_path: Path) -> str:
48
+ """
49
+ Reads the content of a file.
50
+ """
51
+ try:
52
+ with open(file_path, "r", encoding="utf-8") as f:
53
+ return f.read()
54
+ except Exception as e:
55
+ st.error(f"Error loading {file_path}: {e}")
56
+ return ""
57
+
58
+
59
+ def add_custom_css():
60
+ """
61
+ Loads and injects external CSS into the Streamlit app.
62
+ """
63
+ css_path = RESOURCE_PATH / "first_page.css"
64
+ css_content = load_file_content(css_path)
65
+ if css_content:
66
+ st.markdown(f"<style>{css_content}</style>", unsafe_allow_html=True)
67
+
68
+
69
+ def display_landing_page():
70
+ """
71
+ Loads and displays the landing page Markdown content.
72
+ """
73
+ img_data = get_base64_of_image(RESOURCE_PATH / "agi_logo.png")
74
+ img_src = f"data:image/png;base64,{img_data}"
75
+ md_content = f"""
76
+ <div style="background-color: #333333; padding: 20px; border-radius: 10px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); max-width: 800px; margin: 20px auto;">
77
+ <div style="display: flex; align-items: center; justify-content: center;">
78
+ <h1 style="margin: 0; padding: 0 10px 0 0;">Welcome to AGILAB</h1>
79
+ <img src="{img_src}" alt="AGI Logo" style="width:100px;">
80
+ </div>
81
+ <div style="text-align: center;">
82
+ <strong style="color: black;">a step further toward AGI</strong>
83
+ </div>
84
+ </div>
85
+ <div class="uvp-highlight">
86
+ <strong>Founding Concept:</strong> AGILAB outlines a method for scaling into a project’s execution environment without the need for virtualization or containerization (such as Docker). The approach involves encapsulating an app's logic into two components: a worker (which is scalable and free from dependency constraints) and a manager (which is easily integrable due to minimal dependency requirements). This design enables seamless integration within a single app, contributing to the move toward Artificial General Intelligence (AGI).
87
+ </div>
88
+ <div class="uvp-highlight">
89
+ <strong>AGILAB</strong>: Revolutionizing Data Science Experimentation with Zero Integration Hassles. As a comprehensive framework built on 50KLOC of pure Python and powered by Gen AI and ML, AGILAB scales effortlessly—from embedded systems to the cloud—empowering seamless collaboration on data insights and predictive modeling.
90
+ </div>
91
+ <p><strong>Key Features:</strong></p>
92
+ <ul>
93
+ <li><strong>Strong AI Enabler</strong>: Algos Integrations.</li>
94
+ <li><strong>Engineering AI Enabler</strong>: Feature Engineering.</li>
95
+ <li><strong>Availability</strong>: Works online and in standalone mode.</li>
96
+ <li><strong>Enhanced Deployment Productivity</strong>: Automates virtual environment deployment.</li>
97
+ <li><strong>Enhanced Coding Productivity</strong>: Seamless integration with openai-api.</li>
98
+ <li><strong>Enhanced Scalability</strong>: Distributes both data and algorithms on a cluster.</li>
99
+ <li><strong>User-Friendly Interface for Data Science</strong>: Integration of Jupyter-ai and ML Flow.</li>
100
+ <li><strong>Advanced Execution Tools</strong>: Enables Map Reduce and Direct Acyclic Graph Orchestration.</li>
101
+ </ul>
102
+ <p>
103
+ With AGILAB, there’s no need for additional integration—our all-in-one framework is ready to deploy, enabling you to focus on innovation rather than setup.
104
+ </p>
105
+ <div class="uvp-highlight">
106
+ <strong>Tips:</strong> To benefit from AGI cluster automation functionality, all you need is <strong>agi-core</strong> and <strong>agi-env</strong>. This means you can remove the lab and view directories. Historically, AGILAB was developed as a playground for agi-core.
107
+ </div>
108
+ """
109
+ st.markdown(md_content, unsafe_allow_html=True)
110
+
111
+
112
+ def page():
113
+ """
114
+ Display the landing page for AGILAB.
115
+ """
116
+ display_landing_page()
117
+ cols = st.columns(2)
118
+ help_file = Path(st.session_state["env"].help_path) / "index.html"
119
+ if cols[0].button("Read Documentation", type="tertiary", use_container_width=True):
120
+ open_docs(st.session_state["env"], help_file, "project-editor")
121
+ if cols[1].button("Get Started", type="tertiary", use_container_width=True):
122
+ st.write("Redirecting to the main application...")
123
+ st.session_state.current_page = "▶️ EDIT"
124
+ st.rerun()
125
+ current_year = datetime.now().year
126
+ st.markdown(
127
+ f"""
128
+ <div class='footer'>
129
+ &copy; 2020-{current_year} Thales SIX GTS. All rights reserved.
130
+ </div>
131
+ """,
132
+ unsafe_allow_html=True,
133
+ )
134
+
135
+
136
+ def main():
137
+
138
+ from agi_env.agi_env import AgiEnv
139
+ env = AgiEnv("flight", with_lab=True, verbose=True)
140
+ # Global resource path
141
+
142
+ # --- Command-Line Argument Parsing ---
143
+ parser = argparse.ArgumentParser(
144
+ description="Run the AGI Streamlit App with optional parameters."
145
+ )
146
+ parser.add_argument(
147
+ "--cluster-credentials",
148
+ type=str,
149
+ help="Cluster credentials (username:password)",
150
+ default=None
151
+ )
152
+ parser.add_argument(
153
+ "--openai-api-key",
154
+ type=str,
155
+ help="OpenAI API key (mandatory)",
156
+ default=None
157
+ )
158
+ args, unknown = parser.parse_known_args()
159
+
160
+ # --- Retrieve OpenAI API Key ---
161
+ openai_api_key = env.OPENAI_API_KEY if env.OPENAI_API_KEY else args.openai_api_key
162
+ if not openai_api_key:
163
+ # Prompt only if no value exists in the environment or CLI.
164
+ openai_api_key = input("Enter OpenAI API key: ").strip()
165
+ if not openai_api_key:
166
+ print("Error: Missing mandatory parameter: --openai-api-key")
167
+ sys.exit(1)
168
+ else:
169
+ print("Found OpenAI API key; skipping prompt.")
170
+
171
+ # --- Retrieve Cluster Credentials ---
172
+ cluster_credentials = env.AGI_CREDENTIALS if env.AGI_CREDENTIALS else args.cluster_credentials
173
+ if cluster_credentials is None:
174
+ # Prompt only if no cluster credentials exist.
175
+ cluster_enabled = input("Is cluster available? [N/y]: ").strip().lower() or "n"
176
+ if cluster_enabled == "y":
177
+ ssh_key_set = input("Is SSH key set? [N/y]: ").strip().lower() or "n"
178
+ if ssh_key_set == "y":
179
+ cluster_credentials = input("Enter user (SSH key is set): ").strip()
180
+ else:
181
+ cluster_credentials = input("Enter cluster credentials (user:password): ").strip()
182
+ else:
183
+ cluster_credentials = ""
184
+ else:
185
+ print("Found cluster credentials; skipping prompt.")
186
+
187
+
188
+ # -------------------- Setup AgiEnv -------------------- #
189
+ env.set_openai_api_key(openai_api_key)
190
+ env.set_agi_credentials(cluster_credentials)
191
+
192
+ # -------------------- Navigation and Page Rendering -------------------- #
193
+ try:
194
+ if "current_page" not in st.session_state:
195
+ st.session_state.current_page = "AGILAB"
196
+
197
+ if st.session_state.current_page == "AGILAB":
198
+ st.session_state.current_page = None
199
+ page()
200
+ elif st.session_state.current_page == "▶️ EDIT":
201
+ st.session_state.current_page = None
202
+ page_module = importlib.import_module("pages.▶️ EDIT")
203
+ page_module.main()
204
+ else:
205
+ page()
206
+ except Exception as e:
207
+ st.error(f"An error occurred: {e}")
208
+ import traceback
209
+ st.error(traceback.format_exc())
210
+
211
+
212
+ # -------------------- Run the App -------------------- #
213
+ if __name__ == "__main__":
214
+ # Set page configuration before any Streamlit commands.
215
+ st.set_page_config(
216
+ menu_items=get_about_content(), # Adjust if necessary
217
+ layout="wide"
218
+ )
219
+ add_custom_css()
220
+ main()
agi_gui/__init__.py ADDED
File without changes
agi_gui/agi_copilot.py ADDED
@@ -0,0 +1,33 @@
1
+ # BSD 3-Clause License
2
+ #
3
+ # Copyright (c) 2025, Jean-Pierre Morard, THALES SIX GTS France SAS
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9
+ # 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10
+ # 3. Neither the name of Jean-Pierre Morard nor the names of its contributors, or THALES SIX GTS France SAS, may be used to endorse or promote products derived from this software without specific prior written permission.
11
+ #
12
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13
+
14
+ import traceback
15
+
16
+ import streamlit as st
17
+
18
+ df = st.session_state.loaded_df
19
+ snippet_file = st.session_state.snippet_file
20
+
21
+ with open(snippet_file, "r") as snippet:
22
+ try:
23
+ exec(snippet.read())
24
+
25
+ except KeyError as err:
26
+ raise KeyError(
27
+ f"{snippet_file}: columns name {err.args[0]} is not present in the dateframe, "
28
+ f"please rename it with a name of a column already in the dataset"
29
+ ) from err
30
+
31
+ except Exception as err:
32
+ st.error(f"```{snippet_file}: {err}\n{traceback.format_exc()}```")
33
+ st.session_state.data = df
agi_gui/lab_run.py ADDED
@@ -0,0 +1,76 @@
1
+ # BSD 3-Clause License
2
+ #
3
+ # Copyright (c) 2025, Jean-Pierre Morard, THALES SIX GTS France SAS
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9
+ # 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10
+ # 3. Neither the name of Jean-Pierre Morard nor the names of its contributors, or THALES SIX GTS France SAS, may be used to endorse or promote products derived from this software without specific prior written permission.
11
+ #
12
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13
+
14
+ import argparse
15
+ import sys
16
+ from pathlib import Path
17
+ import streamlit.web.cli as stcli
18
+
19
+ def check_environment():
20
+
21
+ # Check if current directory is acceptable:
22
+ cwd = Path.cwd()
23
+ # For example, accept if the cwd contains 'pyproject.toml'
24
+ if not (cwd / "pyproject.toml").exists() and "agilab/src/fwk/gui" not in str(cwd):
25
+ print("Error: Please run this command from a directory that contains your agilab project (e.g. the project root or agilab/src/fwk/gui).")
26
+ sys.exit(1)
27
+
28
+ # Check if the package is installed (optional):
29
+ try:
30
+ import agi_gui # or any module from your package
31
+ except ImportError:
32
+ print("Error: The agilab package is not installed in this environment.")
33
+ sys.exit(1)
34
+
35
+ def main():
36
+
37
+ check_environment()
38
+
39
+ parser = argparse.ArgumentParser(
40
+ description="Run AGILAB application with custom options."
41
+ )
42
+ parser.add_argument(
43
+ "--cluster-credentials", type=str, help="Cluster account user:password", default=None
44
+ )
45
+ parser.add_argument(
46
+ "--openai-api-key", type=str, help="OpenAI API key", default=None
47
+ )
48
+ # Parse known arguments; extra arguments are captured in `unknown`
49
+ args, unknown = parser.parse_known_args()
50
+
51
+ # Determine the target script (adjust path if necessary)
52
+ target_script = str(Path(__file__).parent / "AGILAB.py")
53
+
54
+ # Build the base argument list for Streamlit.
55
+ new_argv = ["streamlit", "run", target_script]
56
+
57
+ # Collect custom arguments.
58
+ custom_args = []
59
+ if args.cluster_credentials is not None:
60
+ custom_args.extend(["--cluster-credentials", args.cluster_credentials])
61
+ if args.openai_api_key is not None:
62
+ custom_args.extend(["--openai-api-key", args.openai_api_key])
63
+ if unknown:
64
+ custom_args.extend(unknown)
65
+
66
+ # Only add the double dash and custom arguments if there are any.
67
+ if custom_args:
68
+ new_argv.append("--")
69
+ new_argv.extend(custom_args)
70
+
71
+ sys.argv = new_argv
72
+ sys.exit(stcli.main())
73
+
74
+
75
+ if __name__ == "__main__":
76
+ main()