Navya-Sree commited on
Commit
a3f36ed
Β·
verified Β·
1 Parent(s): 5ffc95f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +169 -0
app.py CHANGED
@@ -1,4 +1,173 @@
1
  import os
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  import streamlit as st
3
 
4
  from macg.llm_openai import OpenAIResponsesLLM
 
1
  import os
2
+ import glob
3
+ import streamlit as st
4
+ from urllib.parse import urlparse, parse_qs
5
+
6
+ from macg.llm_openai import OpenAIResponsesLLM
7
+ from macg.agents.coder import CoderAgent
8
+ from macg.agents.reviewer import ReviewerAgent
9
+ from macg.agents.tester import TesterAgent
10
+ from macg.orchestrator import Orchestrator
11
+
12
+ st.set_page_config(page_title="Multi-Agent Codegen (OpenAI)", layout="wide")
13
+
14
+ st.title("πŸ€– Multi-Agent Codegen + Review + Testing (OpenAI)")
15
+ st.caption("Coder β†’ Reviewer β†’ Tester loop with pytest verification.")
16
+
17
+ # -----------------------------
18
+ # Helpers
19
+ # -----------------------------
20
+ def parse_openai_uri(uri: str) -> tuple[str, str, str]:
21
+ """
22
+ Supported inputs:
23
+ 1) raw key: sk-... (or rk-...)
24
+ 2) openai://<API_KEY>@api.openai.com?model=gpt-5
25
+ 3) https://api.openai.com/v1?api_key=sk-...&model=gpt-5
26
+
27
+ Returns: (api_key, base_url, model)
28
+ """
29
+ uri = (uri or "").strip()
30
+ default_base = "https://api.openai.com/v1"
31
+ default_model = "gpt-5"
32
+
33
+ if not uri:
34
+ return "", default_base, default_model
35
+
36
+ # If user pastes only the key
37
+ if uri.startswith("sk-") or uri.startswith("rk-") or ("://" not in uri and len(uri) > 20):
38
+ return uri, default_base, default_model
39
+
40
+ u = urlparse(uri)
41
+ q = parse_qs(u.query)
42
+
43
+ # base_url
44
+ if u.scheme in ("http", "https"):
45
+ base_url = f"{u.scheme}://{u.netloc}{u.path}".rstrip("/")
46
+ else:
47
+ base_url = default_base
48
+
49
+ # api_key (query or userinfo)
50
+ api_key = ""
51
+ if "api_key" in q:
52
+ api_key = q["api_key"][0]
53
+ elif "key" in q:
54
+ api_key = q["key"][0]
55
+ elif u.username:
56
+ api_key = u.username
57
+
58
+ model = q.get("model", [default_model])[0]
59
+ return api_key, base_url, model
60
+
61
+
62
+ def build_orchestrator(api_key: str, base_url: str, model: str, temperature: float) -> Orchestrator:
63
+ if not api_key:
64
+ raise RuntimeError("OpenAI key missing. Paste it in the URI field in the sidebar.")
65
+
66
+ llm = OpenAIResponsesLLM(
67
+ api_key=api_key,
68
+ base_url=base_url,
69
+ model=model,
70
+ temperature=float(temperature),
71
+ max_output_tokens=900,
72
+ )
73
+ coder = CoderAgent(llm)
74
+ reviewer = ReviewerAgent(llm)
75
+ tester = TesterAgent(llm)
76
+ return Orchestrator(coder=coder, reviewer=reviewer, tester=tester)
77
+
78
+
79
+ # -----------------------------
80
+ # Sidebar controls
81
+ # -----------------------------
82
+ with st.sidebar:
83
+ st.header("OpenAI Connection")
84
+
85
+ uri = st.text_input(
86
+ "OpenAI URI (paste key here)",
87
+ type="password",
88
+ value="",
89
+ help=(
90
+ "Paste either:\n"
91
+ "β€’ Just the key: sk-...\n"
92
+ "β€’ openai://sk-XXX@api.openai.com?model=gpt-5\n"
93
+ "β€’ https://api.openai.com/v1?api_key=sk-XXX&model=gpt-5"
94
+ ),
95
+ )
96
+
97
+ api_key, base_url, model_from_uri = parse_openai_uri(uri)
98
+
99
+ model = st.text_input("Model", value=model_from_uri)
100
+ temperature = st.slider("Temperature", 0.0, 1.0, 0.2, 0.05)
101
+ max_iters = st.slider("Max iterations", 1, 6, 3)
102
+
103
+ st.divider()
104
+ st.caption("Debug (optional)")
105
+ if st.checkbox("Show import paths / files"):
106
+ st.write("PYTHONPATH =", os.getenv("PYTHONPATH"))
107
+ st.write("sys.path =", __import__("sys").path)
108
+ st.write("/app/src exists?", os.path.exists("/app/src"))
109
+ st.write("/app/src/macg exists?", os.path.exists("/app/src/macg"))
110
+ st.write("Files in /app/src/macg:", glob.glob("/app/src/macg/*"))
111
+
112
+ if not api_key:
113
+ st.warning("Paste your OpenAI key in the URI field to run.")
114
+
115
+
116
+ # -----------------------------
117
+ # Main UI
118
+ # -----------------------------
119
+ default_task = (
120
+ "Implement a function fizzbuzz(n: int) -> list[str] that returns strings for 1..n.\n"
121
+ "- Multiples of 3 -> 'Fizz'\n"
122
+ "- Multiples of 5 -> 'Buzz'\n"
123
+ "- Multiples of both -> 'FizzBuzz'\n"
124
+ "Return the list of length n.\n"
125
+ "Edge cases: n <= 0 should return an empty list."
126
+ )
127
+
128
+ task = st.text_area("Task", value=default_task, height=180)
129
+
130
+ colA, colB = st.columns([1, 1])
131
+ run_btn = colA.button("Run Agents", type="primary", use_container_width=True)
132
+ clear_btn = colB.button("Clear Output", use_container_width=True)
133
+
134
+ if clear_btn:
135
+ st.session_state.pop("result", None)
136
+
137
+ if run_btn:
138
+ try:
139
+ orch = build_orchestrator(api_key=api_key, base_url=base_url, model=model, temperature=temperature)
140
+ with st.spinner("Running Coder β†’ Reviewer β†’ Tester..."):
141
+ result = orch.run(task=task, max_iters=int(max_iters))
142
+ st.session_state["result"] = result
143
+ except Exception as e:
144
+ st.error(str(e))
145
+
146
+ result = st.session_state.get("result")
147
+
148
+ if result:
149
+ top1, top2, top3 = st.columns([1, 1, 1])
150
+ top1.metric("Passed", "βœ… Yes" if result.passed else "❌ No")
151
+ top2.metric("Iterations", str(result.iteration))
152
+ top3.metric("Module", result.module_name)
153
+
154
+ st.divider()
155
+
156
+ left, right = st.columns([1, 1])
157
+
158
+ with left:
159
+ st.subheader("Generated Code")
160
+ st.code(result.code or "", language="python")
161
+
162
+ st.subheader("Review Notes")
163
+ st.text(result.review_notes or "")
164
+
165
+ with right:
166
+ st.subheader("Generated Tests")
167
+ st.code(result.tests or "", language="python")
168
+
169
+ st.subheader("Test Report")
170
+ st.text(result.test_report or "")
171
  import streamlit as st
172
 
173
  from macg.llm_openai import OpenAIResponsesLLM