prashantmatlani commited on
Commit
f54201d
·
1 Parent(s): 931d9f1

updated agentic functions

Browse files
README_CoderG_05182026.md ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # CoderG — Autonomous Multi-Agent Technical Architecture & Documentation Agent
2
+
3
+ CoderG is an agentic, multi-worker workflow orchestrator designed to analyze software repositories, generate comprehensive course content or developer documentation, and autonomously manage the version control deployment lifecycle.
4
+
5
+ CoderG is a high-performance, modular AI agentic application designed to process source repositories, generate production-grade technical engineering document architectures, compile modular asset packages, and autonomously manage the deployment life cycle.
6
+
7
+ Constructed on a foundation of **First Principles Thinking** and constrained by **Ockham's Razor**, CoderG divides high-complexity generative operations from structural file modification and remote system mutations. It introduces a strict human-in-the-loop authorization tower to review, authenticate, and commit assets safely.
8
+
9
+ ---
10
+
11
+ ## 🎯 Project Profile
12
+
13
+ ### 1. Project Scope
14
+ The core boundary of CoderG encompasses providing an automated, terminal-isolated development helper that acts as a technical partner and instructor. The application reads codebase contexts, dynamically builds comprehensive learning or deployment documentation frameworks, writes files natively across diverse extensions, provisions remote endpoints, and manages full git versioning pipelines securely.
15
+
16
+ ### 2. Core Requirements
17
+ * **Context Token Safety:** Must dynamically handle dense repository files without triggering Context Length or Tokens Per Minute (TPM) failures.
18
+ * **Decoupled Responsibilities:** Code execution, file construction, git transportation, and logging must reside in fully decoupled, isolated scripts.
19
+ * **Visual Progress Feedback:** Provide instant, transparent status tracking of ongoing localized mutations using distinct UI presentation techniques.
20
+ * **Explicit Gatekeeping:** No automated generation is allowed to interact with external git platforms without manual credential approval from the workspace tower.
21
+ * **Destruction Resilience:** Must preserve historical artifact records using shadow copies (`_-1`) before fresh write events occur.
22
+
23
+ ### 3. Expected Outcome
24
+ A production-ready orchestration workflow tool that cuts code asset production time by automating file creation, organization, and remote repository hosting.
25
+
26
+ ---
27
+
28
+ ## 🛠️ Core Tools & Tech-Stack Employed
29
+
30
+ * **Presentation Engine:** `Gradio (v5+)` — Used for its reactive state mechanics, streaming token interface pipelines, and robust asynchronous event handshaking loops.
31
+ * **Inference Core:** `Groq Client SDK` (`llama-3.1-8b-instant`) — Running at zero temperature to guarantee technical predictability and programmatic format compliance.
32
+ * **Transport Driver:** `GitPython Framework` & `Native Git Core` — Powers local repository instantiation, metadata index additions, and tracking system commits.
33
+ * **Infrastructure Layer:** `GitHub REST API v3 Engine` — Automates remote cloud platform discovery, profile querying, and repository initialization on headless systems.
34
+ * **Format Compilation Compilers:** `PyYAML`, `TOML`, `python-docx` — Decodes plaintext generator responses directly into precise configuration scripts and professional document layouts.
35
+
36
+ ---
37
+
38
+
39
+ ---
40
+
41
+ ## 🏗️ Core Architecture Overview
42
+
43
+ CoderG bypasses monolithic script patterns by delegating tasks across highly specialized micro-agents:
44
+
45
+ ┌──────────────────────────────┐
46
+ │ app.py (Manager) │ <── Gradio Presentation Control
47
+ └──────────────┬───────────────┘
48
+
49
+ ┌───────────────────────┼───────────────────────┐
50
+ ▼ ▼ ▼
51
+ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐
52
+ │ core_logic.py │ │ file_agent.py │ │ git_agent.py │
53
+ │ (The Brain) │ │ (The Writer) │ │ (The Courier) │
54
+ └────────┬───────┘ └────────┬───────┘ └────────┬───────┘
55
+ │ │ │
56
+ └───────────────────────┼───────────────────────┘
57
+
58
+ ┌──────────────────────────┐
59
+ │ agent_logging.py (Audit) │ ──> outputs/agent.log
60
+ └──────────────────────────┘
61
+
62
+
63
+ ## 📐 System Flowchart & Interaction Model
64
+
65
+ The architectural diagram below traces an instruction's path as it travels through CoderG's isolated processing channels:
66
+
67
+
68
+ [User Input ]
69
+
70
+
71
+ ┌──────────┐ Streams Text Tokens
72
+ │ app.py │ <───────────────────────────────┐
73
+ └────┬─────┘ │
74
+ │ Invokes Event Processing │
75
+ ▼ │
76
+ ┌──────────────┐ Passes Raw Artifacts ┌──────────────┐
77
+ │core_logic.py │ ─────────────────────> │file_agent.py │
78
+ └──────────────┘ └──────┬───────┘
79
+ │ Writes Workspace Files
80
+
81
+ ┌──────────────┐ Executes Remote Push ┌──────────────┐
82
+ │git_agent.py │ <───────────────────── │ outputs/ │ ◄── [Creates Backups]
83
+ └──────┬───────┘ via Control Tower └──────────────┘
84
+
85
+ ├─► [API Provision check] ──► Pushes Assets to Remote GitHub Target
86
+
87
+ ┌──────────────┐
88
+ │ temp_repo/ │ ──► Purges Folder Completely on Termination (Zero Footprint)
89
+ └──────────────┘
90
+
91
+
92
+ ### Module Component Breakdown/Descriptions
93
+ 1. **`app.py` (Control Tower / UI Layer):** A 3-column asymmetric Gradio interface managing dynamic conversation sessions, asynchronous text streaming execution, state tracking, and explicit telemetry log piping.
94
+
95
+ * **Status:** Fully Functional.
96
+ * **Core Logic:** Implements a stable 3-column structural view layout. The left column acts as a persistent dataset navigation engine for conversation histories. The central window coordinates text message rendering. The right panel houses the interactive authorization settings controlling repository creation parameters.
97
+ * **Key Mechanisms:** Orchestrates async `.then()` processing chains to cleanly refresh components sequentially while tracking persistent chat identifiers.
98
+
99
+ 2. **`core_logic.py` (Brain / LLM / Reasoning Engine):** Handles user request context routing, applies token-safety cutoff mechanisms, injects system architectures via systemic prompt directives, and calls modern inference pipelines (Groq API).
100
+
101
+ * **Status:** Fully Functional.
102
+ * **Core Logic:** Handles file reading, content truncation thresholds (~3000 tokens), system prompt rules, and calls the Groq client platform.
103
+ * **Key Mechanisms:** Slices long conversational histories down to the last **3 active turns** to maintain strict token boundaries. Integrates a shadow copying mechanism that copies pre-existing assets into a historical `_-1` backup state right before overwriting files.
104
+
105
+ 3. **`file_agent.py` (Workspace Writer):** A localized multi-format parser handling safe disk input/output actions. It automatically isolates content streams and securely compiles data structures into native `.md`, `.txt`, `.yaml`, `.toml`, or `.docx` layouts.
106
+
107
+ * **Status:** Fully Functional.
108
+ * **Core Logic:** A script dedicated solely to local file modification. It handles raw text parsing and safely organizes formatting boundaries for distinct output types.
109
+ * **Key Mechanisms:** Maps extension rules dynamically to protect data layout parsing when building structures across text, markdown, configuration tables, or document packages.
110
+
111
+ 4. **`git_agent.py` (Transport Courier):** Performs hybrid automated Git routines. It queries the remote GitHub REST API v3 engine to provision missing public/private code workspaces dynamically under a dedicated robot account, tracks changes, handles file staging, and executes local cleanup routines.
112
+
113
+ * **Status:** Fully Functional.
114
+ * **Core Logic:** Encapsulates external remote connections. It polls GitHub endpoints via REST queries, builds missing public repositories under a dedicated robot account profile, handles staging, and commits files.
115
+ * **Key Mechanisms:** Uses explicit `finally` cleanup paths to run full directory purges on `temp_repo/`, leaving a zero storage footprint inside host containers.
116
+
117
+ 5. **`agent_logging.py` (System Auditor):** A zero-dependency, transactional time-stamped tracker writing every systemic action, error, observation, or confirmation out to a safe operational log file (`outputs/agent.log`).
118
+
119
+ * **Status:** Fully Functional.
120
+ * **Core Logic:** A file utility tracking internal state changes.
121
+ * **Key Mechanisms:** Appends structured, timestamped logs out to `outputs/agent.log` to track initialization tasks, file events, or deployment problems.
122
+
123
+ > Worker module includes:
124
+
125
+ * agent_logging.py,
126
+ * file_agent.py,
127
+ * git_agent.py
128
+
129
+ ---
130
+
131
+ ## 🛠️ Tech-Stack & Framework Layering
132
+
133
+ | Core Domain | Technology Component | Purpose |
134
+ | :--- | :--- | :--- |
135
+ | **User Interface** | Gradio (v5+) | State persistence, streaming Markdown token rendering, and split control-column configuration. |
136
+ | **Inference Core** | Groq SDK (`llama-3.1-8b-instant`) | Ultra-low latency chat completion engine with streaming iterations at zero temperature for predictive consistency. |
137
+ | **Version Control** | GitPython Framework & Native Git Core | Facilitates execution of low-level `clone`, `add`, `commit`, and `push` actions within local filesystems. |
138
+ | **Cloud Provisioning** | GitHub REST API v3 Engine | Automates remote repository discovery and programmatic user account setup. |
139
+ | **Structure Storage** | PyYAML, TOML, python-docx | Parses plaintext outputs into production configuration files and office-compliant word documents. |
140
+
141
+ ---
142
+
143
+ ## 🎛️ Implemented System Configurations
144
+
145
+ ### 1. The Token-Safe History Slicing Mirror
146
+ To circumvent Context Window exhaustion (TPM limits) when processing dense codebases, `core_logic.py` dynamically intercepts file contexts, applies hard char limits (~3,000 tokens), and strictly slices ongoing history states to keep only the **last 3 message turns** active during inference.
147
+
148
+ ### 2. Autonomous Repository Provisioning
149
+ The system does not expect target GitHub workspaces to exist in advance. When the deployment button fires, `git_agent.py` sends a network request to look for the repository profile. If a `404 Not Found` returns, it builds the project repository programmatically under the automated account credentials before tracking your files.
150
+
151
+ ### 3. Historical Version State Backup (`_-1` Directive)
152
+ To prevent destructive loss of material during active prompt generations, the workspace performs file version tracking. Prior to writing a newly compiled file (e.g., `COURSE_README.md`), any pre-existing copy inside the workspace folder is replicated and moved to a historical shadow file matching a `_-1` naming convention (`COURSE_README_-1.md`).
153
+
154
+ ### 4. Zero-Footprint Dynamic Storage Purification
155
+ To keep internal host resources, containers, or Hugging Face spaces lean and unbloated by redundant tracking configurations, `git_agent.py` uses explicit `finally` execution trees to forcefully execute a deep `shutil.rmtree()` on temporary clone workspaces (`temp_repo/`) immediately following successful network pushes.
156
+
157
+ ---
158
+
159
+ ## 🚀 Planned & Strategic Enhancements
160
+
161
+ ### Phase 1: Context Capture Optimizations
162
+ * **Recursive Repository Ingestion Tooling:** Replace generic truncations with an iterative script map that traverses subdirectory code layers using structured AST parsing, distilling entire code repositories down to highly accurate technical profiles.
163
+ * **Intelligent File Template Identification:** Teach the system to automatically analyze output patterns. If the LLM generates structure strings starting with `title:` or `[tool.poetry]`, the system will bypass standard markdown strings and save them as `.yaml` or `.toml` variants dynamically.
164
+
165
+ ### Phase 2: Workflow Security & Collaboration Controls
166
+ * **Branch-Based Multi-Staging (PR Workflows):** Transition from making forced commits onto primary branches to pushing automated code changes onto a structured sandbox branch (e.g., `coderg-patch-v1`), followed by raising formal GitHub Pull Requests automatically for team audits.
167
+ * **Dynamic Webhook Observability:** Set up structural web listeners inside the interface. If an external user changes or commits code changes to the target repository directly from GitHub, CoderG can immediately read the webhook updates and synchronize its localized working directories.
168
+
169
+ ### Phase 3: Advanced Diagnostic Monitoring
170
+ * **Live Telemetry Streams:** Upgrade the standard markdown logger block inside the interface
171
+
172
+ ### Active Webhook Synchronizer
173
+ * **Concept:** Set up explicit network listener endpoints inside the backend. If an outside team member modifies or changes files on the remote GitHub target branch directly, CoderG will capture the payload notice and immediately update its local data spaces.
174
+
175
+ ### Deep Abstract Syntax Tree (AST) Mapping
176
+ * **Concept:** Move past basic text truncation methods. Implement a file processing pipeline that scans target directories, strips out junk text blocks, and uses Python's built-in `ast` module to condense whole repositories down to clear functional maps before prompting the model.
177
+
178
+ ### Dynamic Structural Template Matching
179
+ * **Concept:** Upgrade the file compilation engine. Teach `core_logic.py` to identify technical structures programmatically. If an asset block starts with properties like `[tool.poetry]` or `version:`, the agent will bypass generic formatting fallback parameters and write the data directly out under matching `.toml` or `.yaml` file configurations.
180
+
181
+ ### Real-Time Telemetry Streaming
182
+ * **Concept:** Connect a live log viewer component directly onto the Gradio Presentation Tower, streaming changes from `outputs/agent.log` to the UI panel so developers can watch background agent tasks unfold live.
agent_logging.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ # ./agent_logging.py
4
+ # The Logger - Ensures that all agent actions, observations, and errors are logged to a localized log file for traceability and debugging purposes.
5
+
6
+ import os
7
+ from datetime import datetime
8
+
9
+ def log_agent_action(action_type, message):
10
+ """Logs all agent actions, observations, and errors to a localized log file."""
11
+ output_dir = "outputs"
12
+ if not os.path.exists(output_dir):
13
+ os.makedirs(output_dir)
14
+
15
+ log_path = os.path.join(output_dir, "agent.log")
16
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
17
+
18
+ with open(log_path, "a", encoding="utf-8") as log_file:
19
+ log_file.write(f"[{timestamp}] [{action_type.upper()}] {message}\n")
app.py CHANGED
@@ -16,13 +16,14 @@ history_list.click: This is the bridge that makes the sidebar interactive. Witho
16
  import gradio as gr
17
  from core_logic import chat_function
18
  from storage import save_chat, load_history, get_chat_content
 
19
 
20
- with gr.Blocks() as demo:
21
  # This state keeps track of the filename for the current session
22
  chat_id_state = gr.State("")
23
 
24
  with gr.Row():
25
- # --- Sidebar ---
26
  with gr.Column(scale=1, variant="secondary"):
27
  gr.Markdown("### 🛠️ Silicon Architect")
28
  new_btn = gr.Button("➕ New Chat", variant="primary")
@@ -32,18 +33,43 @@ with gr.Blocks() as demo:
32
  components=[gr.Textbox(visible=False)],
33
  label="Recent Conversations",
34
  samples=load_history(),
35
- type="values" # Ensures we get the string value when clicked
 
36
  )
37
 
38
- # --- Main Chat ---
39
- with gr.Column(scale=4):
40
- chatbot = gr.Chatbot(show_label=False, height=700)
41
  chat_input = gr.MultimodalTextbox(
42
  interactive=True,
43
- placeholder="Discuss architecture or upload code...",
44
  show_label=False
45
  )
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  # --- LOGIC FUNCTIONS ---
48
 
49
  def bot_response(message, history, chat_id):
@@ -55,12 +81,6 @@ with gr.Blocks() as demo:
55
  history[-1]["content"] = partial_resp
56
  yield history
57
 
58
- """
59
- def handle_save(history, chat_id):
60
- # Saves the chat and returns the updated list for the sidebar
61
- new_id = save_chat(chat_id, history)
62
- return new_id, load_history()
63
- """
64
  def handle_save(history, chat_id):
65
  # 1. Save the actual data
66
  new_id = save_chat(chat_id, history)
@@ -72,12 +92,24 @@ with gr.Blocks() as demo:
72
  return new_id, gr.update(samples=current_list)
73
 
74
  def load_past_chat(selected_list):
75
- # selected_list comes as [ 'chat_id' ]
76
  chat_id = selected_list[0]
77
  content = get_chat_content(chat_id)
78
  return content, chat_id
79
 
80
- # --- EVENT HANDLERS ---
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
  # 1. Submit Chat -> Stream Response -> Save -> Refresh Sidebar
83
  chat_input.submit(
@@ -97,23 +129,18 @@ with gr.Blocks() as demo:
97
  [chatbot, chat_id_state]
98
  )
99
 
100
- # 3. New Chat Button
101
  new_btn.click(
102
- lambda: ([], "", load_history()),
103
  None,
104
- [chatbot, chat_id_state, history_list]
105
  )
106
 
107
- # 4. "Force Refresh"
108
- # In Gradio, a component's samples are often cached at the moment of the initial load. To ensure the sidebar is truly dynamic, we need to update the gr.Dataset definition and the refresh logic
109
- # To update history_list definition, we add samples_per_page explicitly, ensuring it's not cutting off the list early
110
- history_list = gr.Dataset(
111
- components=[gr.Textbox(visible=False)],
112
- label="Recent Conversations",
113
- samples=load_history(),
114
- type="values",
115
- samples_per_page=20 # Increase this to see more at once
116
  )
117
 
118
-
119
  demo.launch(theme=gr.themes.Soft(), css="styles.css")
 
16
  import gradio as gr
17
  from core_logic import chat_function
18
  from storage import save_chat, load_history, get_chat_content
19
+ from git_agent import manage_github_repo
20
 
21
+ with gr.Blocks(theme=gr.themes.Soft(), css="styles.css") as demo:
22
  # This state keeps track of the filename for the current session
23
  chat_id_state = gr.State("")
24
 
25
  with gr.Row():
26
+ # --- Left Panel: Sidebar History ---
27
  with gr.Column(scale=1, variant="secondary"):
28
  gr.Markdown("### 🛠️ Silicon Architect")
29
  new_btn = gr.Button("➕ New Chat", variant="primary")
 
33
  components=[gr.Textbox(visible=False)],
34
  label="Recent Conversations",
35
  samples=load_history(),
36
+ type="values",
37
+ samples_per_page=20
38
  )
39
 
40
+ # --- Center Panel: Main Core Multimodal Chat ---
41
+ with gr.Column(scale=3):
42
+ chatbot = gr.Chatbot(show_label=False, height=700, type="messages")
43
  chat_input = gr.MultimodalTextbox(
44
  interactive=True,
45
+ placeholder="Discuss architecture or ask CoderG to produce course documentation...",
46
  show_label=False
47
  )
48
 
49
+ # --- Right Panel: Agentic Control Tower ---
50
+ with gr.Column(scale=1, variant="secondary"):
51
+ gr.Markdown("### 🚀 CoderG Authorization Core")
52
+ gr.Markdown("_Authorize code outputs to be compiled into dedicated remote repositories._")
53
+
54
+ target_repo = gr.Textbox(
55
+ label="Target Repository Name",
56
+ placeholder="e.g., advanced-python-course",
57
+ value="dynamic-course-repo"
58
+ )
59
+ commit_txt = gr.Textbox(
60
+ label="Commit Message",
61
+ value="Automated generation via CoderG Agent"
62
+ )
63
+ staged_files = gr.Textbox(
64
+ label="Staged Files (Comma-separated)",
65
+ value="COURSE_README.md"
66
+ )
67
+
68
+ approve_btn = gr.Button("Approve & Push to GitHub", variant="primary")
69
+
70
+ gr.Markdown("#### 📊 Deployment Telemetry Logs")
71
+ output_log = gr.Markdown("_Awaiting local environment staging completion..._")
72
+
73
  # --- LOGIC FUNCTIONS ---
74
 
75
  def bot_response(message, history, chat_id):
 
81
  history[-1]["content"] = partial_resp
82
  yield history
83
 
 
 
 
 
 
 
84
  def handle_save(history, chat_id):
85
  # 1. Save the actual data
86
  new_id = save_chat(chat_id, history)
 
92
  return new_id, gr.update(samples=current_list)
93
 
94
  def load_past_chat(selected_list):
 
95
  chat_id = selected_list[0]
96
  content = get_chat_content(chat_id)
97
  return content, chat_id
98
 
99
+ def push_authorized(repo_name, commit_msg, files_list):
100
+ """Triggers git_agent to build the target repository, clean up local folders, and log tasks."""
101
+ # Cleanly split comma separated lists of files
102
+ files = [f.strip() for f in files_list.split(",") if f.strip()]
103
+
104
+ if not repo_name.strip():
105
+ yield "❌ **Deployment Aborted:** Repository name cannot be empty."
106
+ return
107
+
108
+ yield "◌ _Connecting to GitHub REST API Engine..._"
109
+ result = manage_github_repo(repo_name.strip(), commit_msg, files)
110
+ yield f"{result}"
111
+
112
+ # --- INTERACTION ARCHITECTURE / EVENT HANDLERS ---
113
 
114
  # 1. Submit Chat -> Stream Response -> Save -> Refresh Sidebar
115
  chat_input.submit(
 
129
  [chatbot, chat_id_state]
130
  )
131
 
132
+ # 3. New Chat Button Initialization
133
  new_btn.click(
134
+ lambda: ([], "", load_history(), "_Awaiting local environment staging completion..._"),
135
  None,
136
+ [chatbot, chat_id_state, history_list, output_log]
137
  )
138
 
139
+ # 4. Bind the Control Tower Approve Action button
140
+ approve_btn.click(
141
+ push_authorized,
142
+ [target_repo, commit_txt, staged_files],
143
+ [output_log]
 
 
 
 
144
  )
145
 
 
146
  demo.launch(theme=gr.themes.Soft(), css="styles.css")
app_earlier.py → app_00.py RENAMED
@@ -1,55 +1,55 @@
1
- 
2
- # ./app.py
3
-
4
- """
5
- The Interface Skeleton - The code sets up the navigation panel and the multimodal chat interface
6
- """
7
-
8
-
9
- import gradio as gr
10
- from core_logic import chat_function
11
- from storage import save_chat, load_history, get_chat_content
12
-
13
- with gr.Blocks() as demo:
14
- chat_id_state = gr.State("")
15
-
16
- with gr.Row():
17
- with gr.Column(scale=1, variant="secondary"):
18
- gr.Markdown("### 🛠️ Silicon Architect")
19
- new_btn = gr.Button("➕ New Chat", variant="primary")
20
- history_list = gr.Dataset(
21
- components=[gr.Textbox(visible=False)],
22
- label="Recent Conversations",
23
- samples=load_history()
24
- )
25
-
26
- with gr.Column(scale=4):
27
- chatbot = gr.Chatbot(show_label=False, height=700)
28
- chat_input = gr.MultimodalTextbox(
29
- interactive=True,
30
- placeholder="Discuss architecture or upload code...",
31
- show_label=False
32
- )
33
-
34
- def bot_response(message, history):
35
- # 1. Add User Message
36
- user_content = message["text"]
37
- history.append({"role": "user", "content": user_content})
38
-
39
- # 2. Add empty Assistant Message to be filled
40
- history.append({"role": "assistant", "content": ""})
41
-
42
- # 3. Stream the response
43
- # history[:-1] sends everything EXCEPT the empty assistant slot we just made
44
- for partial_resp in chat_function(message, history[:-1]):
45
- history[-1]["content"] = partial_resp
46
- yield history
47
-
48
- # Event Handlers
49
- chat_input.submit(bot_response, [chat_input, chatbot], [chatbot]).then(
50
- lambda h: save_chat(None, h), [chatbot], None
51
- )
52
-
53
- new_btn.click(lambda: ([], ""), None, [chatbot, chat_id_state])
54
-
55
  demo.launch(theme=gr.themes.Soft(), css="styles.css")
 
1
+ 
2
+ # ./app.py
3
+
4
+ """
5
+ The Interface Skeleton - The code sets up the navigation panel and the multimodal chat interface
6
+ """
7
+
8
+
9
+ import gradio as gr
10
+ from core_logic import chat_function
11
+ from storage import save_chat, load_history, get_chat_content
12
+
13
+ with gr.Blocks() as demo:
14
+ chat_id_state = gr.State("")
15
+
16
+ with gr.Row():
17
+ with gr.Column(scale=1, variant="secondary"):
18
+ gr.Markdown("### 🛠️ Silicon Architect")
19
+ new_btn = gr.Button("➕ New Chat", variant="primary")
20
+ history_list = gr.Dataset(
21
+ components=[gr.Textbox(visible=False)],
22
+ label="Recent Conversations",
23
+ samples=load_history()
24
+ )
25
+
26
+ with gr.Column(scale=4):
27
+ chatbot = gr.Chatbot(show_label=False, height=700)
28
+ chat_input = gr.MultimodalTextbox(
29
+ interactive=True,
30
+ placeholder="Discuss architecture or upload code...",
31
+ show_label=False
32
+ )
33
+
34
+ def bot_response(message, history):
35
+ # 1. Add User Message
36
+ user_content = message["text"]
37
+ history.append({"role": "user", "content": user_content})
38
+
39
+ # 2. Add empty Assistant Message to be filled
40
+ history.append({"role": "assistant", "content": ""})
41
+
42
+ # 3. Stream the response
43
+ # history[:-1] sends everything EXCEPT the empty assistant slot we just made
44
+ for partial_resp in chat_function(message, history[:-1]):
45
+ history[-1]["content"] = partial_resp
46
+ yield history
47
+
48
+ # Event Handlers
49
+ chat_input.submit(bot_response, [chat_input, chatbot], [chatbot]).then(
50
+ lambda h: save_chat(None, h), [chatbot], None
51
+ )
52
+
53
+ new_btn.click(lambda: ([], ""), None, [chatbot, chat_id_state])
54
+
55
  demo.launch(theme=gr.themes.Soft(), css="styles.css")
app_01.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 
2
+ # ./app.py
3
+
4
+ """
5
+ The Interface Skeleton - The code sets up the navigation panel and the multimodal chat interface
6
+
7
+ The .then() chain: Previously, the save happened "in the background." Now, handle_save explicitly returns the new load_history() results to the history_list component, causing it to "re-render" with the new chat visible.
8
+
9
+ The chat_id_state: By passing this back and forth, the app knows if it should update an existing file in the HF Dataset or create a new one.
10
+
11
+ history_list.click: This is the bridge that makes the sidebar interactive. Without this event, clicking the "Recent Conversations" wouldn't do anything.
12
+
13
+ """
14
+
15
+
16
+ import gradio as gr
17
+ from core_logic import chat_function
18
+ from storage import save_chat, load_history, get_chat_content
19
+
20
+ with gr.Blocks() as demo:
21
+ # This state keeps track of the filename for the current session
22
+ chat_id_state = gr.State("")
23
+
24
+ with gr.Row():
25
+ # --- Sidebar ---
26
+ with gr.Column(scale=1, variant="secondary"):
27
+ gr.Markdown("### 🛠️ Silicon Architect")
28
+ new_btn = gr.Button("➕ New Chat", variant="primary")
29
+
30
+ # The sidebar component
31
+ history_list = gr.Dataset(
32
+ components=[gr.Textbox(visible=False)],
33
+ label="Recent Conversations",
34
+ samples=load_history(),
35
+ type="values" # Ensures we get the string value when clicked
36
+ )
37
+
38
+ # --- Main Chat ---
39
+ with gr.Column(scale=4):
40
+ chatbot = gr.Chatbot(show_label=False, height=700)
41
+ chat_input = gr.MultimodalTextbox(
42
+ interactive=True,
43
+ placeholder="Discuss architecture or upload code...",
44
+ show_label=False
45
+ )
46
+
47
+ # --- LOGIC FUNCTIONS ---
48
+
49
+ def bot_response(message, history, chat_id):
50
+ user_content = message["text"]
51
+ history.append({"role": "user", "content": user_content})
52
+ history.append({"role": "assistant", "content": ""})
53
+
54
+ for partial_resp in chat_function(message, history[:-1]):
55
+ history[-1]["content"] = partial_resp
56
+ yield history
57
+
58
+ """
59
+ def handle_save(history, chat_id):
60
+ # Saves the chat and returns the updated list for the sidebar
61
+ new_id = save_chat(chat_id, history)
62
+ return new_id, load_history()
63
+ """
64
+ def handle_save(history, chat_id):
65
+ # 1. Save the actual data
66
+ new_id = save_chat(chat_id, history)
67
+ # 2. Get the latest from hub
68
+ current_list = load_history()
69
+ # 3. Ensure the current one is definitely at the top
70
+ if [new_id] not in current_list:
71
+ current_list.insert(0, [new_id])
72
+ return new_id, gr.update(samples=current_list)
73
+
74
+ def load_past_chat(selected_list):
75
+ # selected_list comes as [ 'chat_id' ]
76
+ chat_id = selected_list[0]
77
+ content = get_chat_content(chat_id)
78
+ return content, chat_id
79
+
80
+ # --- EVENT HANDLERS ---
81
+
82
+ # 1. Submit Chat -> Stream Response -> Save -> Refresh Sidebar
83
+ chat_input.submit(
84
+ bot_response,
85
+ [chat_input, chatbot, chat_id_state],
86
+ [chatbot]
87
+ ).then(
88
+ handle_save,
89
+ [chatbot, chat_id_state],
90
+ [chat_id_state, history_list]
91
+ )
92
+
93
+ # 2. Click Sidebar Item -> Load Content
94
+ history_list.click(
95
+ load_past_chat,
96
+ [history_list],
97
+ [chatbot, chat_id_state]
98
+ )
99
+
100
+ # 3. New Chat Button
101
+ new_btn.click(
102
+ lambda: ([], "", load_history()),
103
+ None,
104
+ [chatbot, chat_id_state, history_list]
105
+ )
106
+
107
+ # 4. "Force Refresh"
108
+ # In Gradio, a component's samples are often cached at the moment of the initial load. To ensure the sidebar is truly dynamic, we need to update the gr.Dataset definition and the refresh logic
109
+ # To update history_list definition, we add samples_per_page explicitly, ensuring it's not cutting off the list early
110
+ history_list = gr.Dataset(
111
+ components=[gr.Textbox(visible=False)],
112
+ label="Recent Conversations",
113
+ samples=load_history(),
114
+ type="values",
115
+ samples_per_page=20 # Increase this to see more at once
116
+ )
117
+
118
+
119
+ demo.launch(theme=gr.themes.Soft(), css="styles.css")
core_logic.py CHANGED
@@ -5,9 +5,27 @@ import os
5
  from groq import Groq
6
  from tools import web_search, parse_file
7
 
 
 
 
 
 
8
  client = Groq(api_key=os.getenv("GROQ_API_KEY"))
9
  model = "llama-3.1-8b-instant"
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  # Compressed for token efficiency
12
  #SYSTEM_PROMPT = (
13
  # "You're a Full-stack AI Engineering Genius. "
@@ -88,6 +106,7 @@ def chat_function(message, history):
88
 
89
  messages.append({"role": "user", "content": prompt})
90
 
 
91
  try:
92
  completion = client.chat.completions.create(
93
  model=model,
@@ -98,10 +117,42 @@ def chat_function(message, history):
98
  )
99
 
100
  response_text = ""
 
101
  for chunk in completion:
102
  if chunk.choices and chunk.choices[0].delta.content:
103
  token = chunk.choices[0].delta.content
104
  response_text += token
105
  yield response_text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  except Exception as e:
107
- yield f"Error: {str(e)}"
 
 
 
5
  from groq import Groq
6
  from tools import web_search, parse_file
7
 
8
+ import yaml
9
+ import toml
10
+ from docx import Document
11
+
12
+
13
  client = Groq(api_key=os.getenv("GROQ_API_KEY"))
14
  model = "llama-3.1-8b-instant"
15
 
16
+ # Verify write permissions to 'outputs' directory
17
+ def verify_permissions():
18
+ test_file = "permission_test.txt"
19
+ try:
20
+ with open(test_file, "w") as f:
21
+ f.write("test")
22
+ os.remove(test_file)
23
+ print("✅ Write permissions verified.")
24
+ except Exception as e:
25
+ print(f"❌ PERMISSION ERROR: {e}")
26
+
27
+ verify_permissions()
28
+
29
  # Compressed for token efficiency
30
  #SYSTEM_PROMPT = (
31
  # "You're a Full-stack AI Engineering Genius. "
 
106
 
107
  messages.append({"role": "user", "content": prompt})
108
 
109
+ # Spliced directly into ./core_logic.py at the bottom of chat_function()
110
  try:
111
  completion = client.chat.completions.create(
112
  model=model,
 
117
  )
118
 
119
  response_text = ""
120
+ # Step 1: Stream the raw LLM output token by token to the user
121
  for chunk in completion:
122
  if chunk.choices and chunk.choices[0].delta.content:
123
  token = chunk.choices[0].delta.content
124
  response_text += token
125
  yield response_text
126
+
127
+ # Step 2: Transition seamlessly to Local File Generation
128
+ yield response_text + "\n\n◌ _File agent initialized: Generating local documentation workspace..._"
129
+
130
+ from file_agent import write_document
131
+ import shutil
132
+
133
+ filename = "COURSE_README.md"
134
+ backup_filename = "COURSE_README_-1.md"
135
+
136
+ # Proactively manage historical backup copy before writing fresh file state
137
+ src_path = os.path.join("outputs", filename)
138
+ dst_path = os.path.join("outputs", backup_filename)
139
+ if os.path.exists(src_path):
140
+ try:
141
+ shutil.copy2(src_path, dst_path)
142
+ except Exception as e:
143
+ from agent_logging import log_agent_action
144
+ log_agent_action("BACKUP_ERROR", f"Failed to cycle historical version file: {str(e)}")
145
+
146
+ # Write fresh incoming file generation
147
+ file_path = write_document(response_text, filename)
148
+
149
+ # Step 3: Inform the UI that the material is staged and ready for the GitHub authorization layer
150
+ if "Error" not in file_path:
151
+ yield response_text + f"\n\n✅ _Files successfully generated in localized staging environment._\n\n◌ _Awaiting authorization control panel to push to GitHub._"
152
+ else:
153
+ yield response_text + f"\n\n❌ _File generation failed: {file_path}_"
154
+
155
  except Exception as e:
156
+ yield f"Error: {str(e)}"
157
+
158
+
core_logic_01.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # ./core_logic.py -> Token-safe
3
+
4
+ import os
5
+ from groq import Groq
6
+ from tools import web_search, parse_file
7
+
8
+ client = Groq(api_key=os.getenv("GROQ_API_KEY"))
9
+ model = "llama-3.1-8b-instant"
10
+
11
+ # Compressed for token efficiency
12
+ #SYSTEM_PROMPT = (
13
+ # "You're a Full-stack AI Engineering Genius. "
14
+ # "Expert in Python (latest production version), Agentic Loops, and FastAPI, NodeJS, HTML, CSS. "
15
+ # "Provide production-ready code with needed comments. Analyze files when provided. Be concise."
16
+ #)
17
+
18
+ SYSTEM_PROMPT = """
19
+ You are the 'Silicon Architect'—a master-stroke Full-stack AI Engineering and Technical Architecture Genius, and a Knowledgeable Instructor.
20
+ Your goal is to provide production-grade, highly optimized solutions for web and mobile AI applications.
21
+
22
+ Expertise:
23
+ . Python (latest production version), Agentic Loops, FastAPI, Scalable Architecture.
24
+ . Provide production-ready code with appropriate comments, based in rigorous technical research.
25
+ . Analyze provided files thoroughly; propose suitable recommendations
26
+ . Be sharp, precise, concise.
27
+
28
+ CORE DIRECTIVES:
29
+ 1. ARCHITECTURAL RIGOR: Always consider scalability, async patterns, and state management.
30
+ 2. AGENTIC EXPERTISE: You understand recurrent-depth simulations, tool-calling, and autonomous loops.
31
+ 3. CODE QUALITY: Write clean, PEP 8 compliant, appropriately commented upon, secure Python/JS code.
32
+ 4. FIRST PRINCIPLES: Base your responses and reasoning in Richard Feynman’s first principles thinking. Break down complex problems into fundamental truths and reason up from there
33
+ 5. PRIORITIZE ESSENTIALS: Focused on - the "must haves" before the "good to have" - having the fundamentals; stay clear of over-engineering
34
+ 5. OCKHAM'S RAZOR: Prefer simple yet robust and scalabie solutions without compromising on needed deliverables.
35
+ 6. INNOVATION: Suggest latest libraries and frameworks (FastAPI, LangGraph, Pydantic AI; but not limited to these).
36
+ 7. ACTIVE CONTRIBUTOR: Actively recommend enhancements yet without jeopardzing the core requirements; the point is to be proactive in identifying potential improvements and optimizations.
37
+ 8. FORESIGHT INSIGHT: Anticipate potential pitfalls and edge cases, have them all proactively addressed in your solutions.
38
+ 9. RESEARCH: If the user asks about new tech, use your Web Search capability to provide factual, up-to-date documentation.
39
+ 10. ERROR HANDLING: Always include robust error handling, write descriptive error messages that include the offending value.
40
+ 11. SECURITY: Always consider security implications, and implement best practices to mitigate vulnerabilities (e.g., input validation, sanitization, secure defaults).
41
+ 12. README.md: While working on projects, prepare and maintain - for each projct - a README.md outlinining:
42
+ . project scope,
43
+ . requrirements,
44
+ . expected outcome,
45
+ . core tools and tech-stack employed,
46
+ . UML, Flowcharts, Block-diagrams, and other graphics as applicable,
47
+ . a brief explanation of each module/file (such *.py, *.html, *.css, *.js, etc.) in the project, with
48
+ . details about functionalities implemented and working, and about pending/planned implementations,
49
+ . other relevant details of use to the DEV team;
50
+ . iterate the foundational README.md as the project progresses, ensuring it aligns with the latest functional state of the project, and maintain a copy of the last updated README.md with the addition of suffix "_-1", such that README_-1.md.
51
+
52
+ PERSONALITY:
53
+ 1. POLITE & ASSERTIVE : Disagree with the user, if needed; never resort to sycophancy.
54
+ 2. INQUIRE: Formulate necessary questions as deemed fit, suggest better alternatives when need be.
55
+ 3. PROFESSIONALISM: You're a Senior AI Solutions Architect, maintain a technical excellence of one professional, grounded, humane.
56
+
57
+ When a user provides files, analyze the requirement, structure, logic before proposing changes.
58
+ """
59
+
60
+ def chat_function(message, history):
61
+ user_text = message.get("text", "")
62
+ files = message.get("files", [])
63
+
64
+ # 1. Process Files with character limits
65
+ context_from_files = ""
66
+ for f in files:
67
+ path = f["path"] if isinstance(f, dict) else f
68
+ file_content = parse_file(path)
69
+ context_from_files += file_content
70
+
71
+ # TRUNCATE FILE CONTEXT: Max ~3000 tokens (approx 12,000 chars)
72
+ if len(context_from_files) > 12000:
73
+ context_from_files = context_from_files[:12000] + "\n...[File Content Truncated for TPM Limits]..."
74
+
75
+ # 2. Research Trigger
76
+ if any(keyword in user_text.lower() for keyword in ["search", "docs", "latest"]):
77
+ research_context = web_search(user_text)
78
+ prompt = f"RESEARCH:\n{research_context}\n\nFILES:\n{context_from_files}\n\nUSER: {user_text}"
79
+ else:
80
+ prompt = f"FILES:\n{context_from_files}\n\nUSER: {user_text}"
81
+
82
+ # 3. Build Messages with History Slicing
83
+ messages = [{"role": "system", "content": SYSTEM_PROMPT}]
84
+
85
+ # ONLY KEEP LAST 3 TURNS: This is the 'Master Stroke' for staying under 6k TPM
86
+ for turn in history[-3:]:
87
+ messages.append({"role": turn["role"], "content": turn["content"]})
88
+
89
+ messages.append({"role": "user", "content": prompt})
90
+
91
+ try:
92
+ completion = client.chat.completions.create(
93
+ model=model,
94
+ messages=messages,
95
+ stream=True,
96
+ temperature=0.0,
97
+ #max_tokens=1024 # Limit response size to prevent mid-stream cuts
98
+ )
99
+
100
+ response_text = ""
101
+ for chunk in completion:
102
+ if chunk.choices and chunk.choices[0].delta.content:
103
+ token = chunk.choices[0].delta.content
104
+ response_text += token
105
+ yield response_text
106
+ except Exception as e:
107
+ yield f"Error: {str(e)}"
108
+
109
+
file_agent.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ # ./file_agent.py
4
+ # The Writer - Encapsulates your content generation logic, properly decoupled from the main interface.
5
+
6
+ import os
7
+ import yaml
8
+ import toml
9
+ from docx import Document
10
+ from agent_logging import log_agent_action
11
+
12
+ def write_document(content, filename):
13
+ """Handles parsing and physical generation of files, then logs the event."""
14
+ output_dir = "outputs"
15
+ if not os.path.exists(output_dir):
16
+ os.makedirs(output_dir)
17
+
18
+ file_path = os.path.join(output_dir, filename)
19
+ ext = os.path.splitext(filename)[1].lower()
20
+
21
+ try:
22
+ if ext in ['.md', '.txt']:
23
+ with open(file_path, "w", encoding="utf-8") as f:
24
+ f.write(content)
25
+ elif ext == '.yaml':
26
+ data = yaml.safe_load(content) if isinstance(content, str) else content
27
+ with open(file_path, "w") as f:
28
+ yaml.dump(data, f)
29
+ elif ext == '.toml':
30
+ data = toml.loads(content) if isinstance(content, str) else content
31
+ with open(file_path, "w") as f:
32
+ toml.dump(data, f)
33
+ elif ext == '.docx':
34
+ doc = Document()
35
+ doc.add_paragraph(content)
36
+ doc.save(file_path)
37
+ else:
38
+ with open(file_path, "w", encoding="utf-8") as f:
39
+ f.write(str(content))
40
+
41
+ log_agent_action("FILE_CREATION", f"Successfully generated {filename}")
42
+ return file_path
43
+ except Exception as e:
44
+ log_agent_action("FILE_ERROR", f"Failed to save {filename}: {str(e)}")
45
+ return f"Error: {str(e)}"
git_agent.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ """
3
+ # ./git_agent.py
4
+
5
+ # The Courier - Features the fixed parameter initialization logic, calls GitHub API to provision new repos under CoderG's dedicated account, and completely clears the transient temp_repo folder after pushing.
6
+ """
7
+
8
+ import os
9
+ import shutil
10
+ import requests
11
+ from git import Repo
12
+ from agent_logging import log_agent_action
13
+
14
+ def manage_github_repo(repo_name, commit_message, files_to_add):
15
+ """Clones, creates missing repos, pushes files, and forces local directory purge."""
16
+ token = os.getenv("GITHUB_TOKEN")
17
+ username = os.getenv("GITHUB_USERNAME")
18
+
19
+ if not token or not username:
20
+ log_agent_action("GIT_ERROR", "Missing GITHUB_TOKEN or GITHUB_USERNAME in environment.")
21
+ return "GIT ERROR: Missing authentication credentials."
22
+
23
+ # 1. Check/Create Repository on GitHub via API
24
+ api_url = "https://api.github.com/user/repos"
25
+ check_url = f"https://api.github.com/repos/{username}/{repo_name}"
26
+ headers = {"Authorization": f"token {token}", "Accept": "application/vnd.github.v3+json"}
27
+
28
+ try:
29
+ response = requests.get(check_url, headers=headers)
30
+ if response.status_code == 404:
31
+ log_agent_action("GIT_PROVISION", f"Repo '{repo_name}' not found. Initializing on GitHub...")
32
+ create_res = requests.post(api_url, json={"name": repo_name, "private": False}, headers=headers)
33
+ if create_res.status_code != 201:
34
+ raise Exception(f"GitHub API creation failed: {create_res.text}")
35
+ log_agent_action("GIT_PROVISION", f"Successfully created remote repo: {repo_name}")
36
+ except Exception as api_err:
37
+ log_agent_action("GIT_ERROR", f"API Verification Phase failed: {str(api_err)}")
38
+ return f"GIT ERROR: {str(api_err)}"
39
+
40
+ # 2. Local Git Actions
41
+ repo_url = f"https://{username}:{token}@github.com/{username}/{repo_name}.git"
42
+ local_path = os.path.join(os.getcwd(), "temp_repo")
43
+
44
+ try:
45
+ if not os.path.exists(local_path):
46
+ repo = Repo.clone_from(repo_url, local_path)
47
+ else:
48
+ repo = Repo(local_path)
49
+
50
+ # Move files from outputs to temp_repo safely
51
+ files_actually_added = 0
52
+ for file in files_to_add:
53
+ src = os.path.join("outputs", file)
54
+ dst = os.path.join(local_path, file)
55
+ if os.path.exists(src):
56
+ shutil.copy2(src, dst)
57
+ repo.index.add([file])
58
+ files_actually_added += 1
59
+ else:
60
+ log_agent_action("GIT_WARN", f"Staged file item '{file}' not found in outputs/ directory. Skipping.")
61
+
62
+ if files_actually_added == 0:
63
+ status_msg = "NOTICE: Commit aborted. None of the listed staged files exist in local storage."
64
+ return status_msg
65
+
66
+ if repo.is_dirty():
67
+ repo.index.commit(commit_message)
68
+ origin = repo.remote(name='origin')
69
+ origin.push()
70
+ log_agent_action("GIT_PUSH", f"Pushed {len(files_to_add)} files to {repo_name}")
71
+ status_msg = f"Success: Repository {repo_name} is live/updated at {repo_url}"
72
+ else:
73
+ log_agent_action("GIT_NOTICE", "No modifications detected; push aborted.")
74
+ status_msg = "NOTICE: No changes detected to commit."
75
+
76
+ except Exception as git_err:
77
+ log_agent_action("GIT_ERROR", f"Local operations failed: {str(git_err)}")
78
+ status_msg = f"GIT ERROR: {str(git_err)}"
79
+ finally:
80
+ # 3. Dynamic Cleanup Execution
81
+ if os.path.exists(local_path):
82
+ shutil.rmtree(local_path, ignore_errors=True)
83
+ log_agent_action("CLEANUP", "Transient directory 'temp_repo' purged successfully.")
84
+
85
+ return status_msg
requirements.txt CHANGED
@@ -7,4 +7,5 @@ python-docx
7
  pandas
8
  tavily-python
9
  groq
10
- openai
 
 
7
  pandas
8
  tavily-python
9
  groq
10
+ openai
11
+ git