kendrickfff commited on
Commit
3fd4339
·
verified ·
1 Parent(s): 170ad78

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +85 -53
app.py CHANGED
@@ -24,7 +24,7 @@ credential = ClientSecretCredential(
24
  )
25
  project = AIProjectClient(credential=credential, endpoint=PROJECT_ENDPOINT)
26
 
27
- # ── Lazy agent fetch (so app boots even if Azure is slow) ─────────
28
  _agent = None
29
 
30
  def get_agent():
@@ -36,15 +36,9 @@ def get_agent():
36
 
37
  # ── Chat logic ────────────────────────────────────────────────────
38
  def respond(user_message: str, history: list, thread_state: dict | None):
39
- """
40
- Gradio calls this for every user message.
41
- - Creates a new Azure thread on first message (per session).
42
- - Sends user message → runs agent → returns assistant reply.
43
- """
44
  if not user_message.strip():
45
  return history, thread_state
46
 
47
- # First message in session → create new thread
48
  if thread_state is None or "thread_id" not in thread_state:
49
  thread = project.agents.threads.create()
50
  thread_state = {"thread_id": thread.id}
@@ -54,14 +48,12 @@ def respond(user_message: str, history: list, thread_state: dict | None):
54
  try:
55
  agent = get_agent()
56
 
57
- # Send user message
58
  project.agents.messages.create(
59
  thread_id=thread_id,
60
  role="user",
61
  content=user_message,
62
  )
63
 
64
- # Run agent
65
  run = project.agents.runs.create_and_process(
66
  thread_id=thread_id,
67
  agent_id=agent.id,
@@ -73,7 +65,6 @@ def respond(user_message: str, history: list, thread_state: dict | None):
73
  "Please try again or start a new conversation."
74
  )
75
  else:
76
- # Get latest assistant message
77
  messages = project.agents.messages.list(
78
  thread_id=thread_id, order=ListSortOrder.DESCENDING
79
  )
@@ -95,76 +86,117 @@ def respond(user_message: str, history: list, thread_state: dict | None):
95
 
96
 
97
  def new_conversation():
98
- """Reset chat history and thread state."""
99
  return [], None
100
 
101
 
102
- # ── Gradio UI ─────────────────────────────────────────────────────
103
- DESCRIPTION = """
104
- # 🤖 Agent Ken PM + Social Impact Copilot
105
-
106
- A **Product Manager Copilot** with a social worker's empathy and harm-reduction lens.
107
- Built on Azure AI Foundry Agent Service.
108
-
109
- **What I can help with:**
110
- - 🔍 Product discovery (JTBD, personas, problem statements)
111
- - 📊 Prioritization (RICE scoring, MoSCoW)
112
- - 📝 PRDs, user stories, acceptance criteria
113
- - 🧪 Experiment design (A/B tests, hypothesis templates)
114
- - 📈 Metrics & OKRs (North Star, funnels, guardrails)
115
- - 🤝 Stakeholder communication (memos, updates, FAQs)
116
- - Inclusive & ethical design considerations
117
-
118
- ---
119
- *Created by Kendrick Filbert • Powered by Azure AI Foundry*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  """
121
 
 
122
  EXAMPLES = [
123
- "Help me write a PRD for a mobile mental health check-in feature",
124
- "Score these 3 features using RICE: onboarding revamp, dark mode, referral program",
125
- "Design an A/B test for our new checkout flow",
126
- "What metrics should I track for a community-driven marketplace?",
127
- "Help me draft a stakeholder memo about delaying our launch by 2 weeks",
128
- "Review this user story for accessibility concerns",
129
  ]
130
 
131
- CSS = """
132
- .gradio-container { max-width: 850px !important; }
133
- footer { display: none !important; }
134
- """
135
-
136
  with gr.Blocks(title="Agent Ken — PM Copilot") as demo:
137
 
138
- gr.Markdown(DESCRIPTION)
 
 
 
 
 
 
139
 
 
140
  chatbot = gr.Chatbot(
141
  label="Agent Ken",
142
- height=500,
 
143
  )
144
 
145
- # State: thread_id per session (not visible to user)
146
  thread_state = gr.State(value=None)
147
 
148
- with gr.Row():
 
149
  msg_input = gr.Textbox(
150
- placeholder="Ask Agent Ken anything about product management...",
151
- label="Your message",
 
152
  scale=5,
153
  lines=1,
154
- max_lines=4,
 
155
  )
156
- send_btn = gr.Button("Send 🚀", variant="primary", scale=1)
157
 
158
- with gr.Row():
159
- clear_btn = gr.Button("🗑️ New Conversation", variant="secondary")
 
160
 
161
- with gr.Accordion("💡 Example prompts", open=False):
 
162
  gr.Examples(
163
  examples=EXAMPLES,
164
  inputs=msg_input,
 
165
  )
166
 
167
- # ── Event bindings ────────────────────────────────────────────
 
 
 
 
 
 
 
168
  send_btn.click(
169
  fn=respond,
170
  inputs=[msg_input, chatbot, thread_state],
@@ -184,4 +216,4 @@ with gr.Blocks(title="Agent Ken — PM Copilot") as demo:
184
 
185
  # ── Launch ────────────────────────────────────────────────────────
186
  if __name__ == "__main__":
187
- demo.launch(server_name="0.0.0.0", server_port=7860, css=CSS, theme=gr.themes.Soft())
 
24
  )
25
  project = AIProjectClient(credential=credential, endpoint=PROJECT_ENDPOINT)
26
 
27
+ # ── Lazy agent fetch ──────────────────────────────────────────────
28
  _agent = None
29
 
30
  def get_agent():
 
36
 
37
  # ── Chat logic ────────────────────────────────────────────────────
38
  def respond(user_message: str, history: list, thread_state: dict | None):
 
 
 
 
 
39
  if not user_message.strip():
40
  return history, thread_state
41
 
 
42
  if thread_state is None or "thread_id" not in thread_state:
43
  thread = project.agents.threads.create()
44
  thread_state = {"thread_id": thread.id}
 
48
  try:
49
  agent = get_agent()
50
 
 
51
  project.agents.messages.create(
52
  thread_id=thread_id,
53
  role="user",
54
  content=user_message,
55
  )
56
 
 
57
  run = project.agents.runs.create_and_process(
58
  thread_id=thread_id,
59
  agent_id=agent.id,
 
65
  "Please try again or start a new conversation."
66
  )
67
  else:
 
68
  messages = project.agents.messages.list(
69
  thread_id=thread_id, order=ListSortOrder.DESCENDING
70
  )
 
86
 
87
 
88
  def new_conversation():
 
89
  return [], None
90
 
91
 
92
+ # ── CSS ───────────────────────────────────────────────────────────
93
+ CSS = """
94
+ /* Center and constrain width */
95
+ .gradio-container {
96
+ max-width: 900px !important;
97
+ margin: 0 auto !important;
98
+ }
99
+
100
+ /* Hide footer */
101
+ footer { display: none !important; }
102
+
103
+ /* Header styling */
104
+ .header-section {
105
+ text-align: center;
106
+ padding: 16px 0 8px 0;
107
+ }
108
+ .header-section h1 {
109
+ font-size: 1.5rem;
110
+ margin-bottom: 4px;
111
+ }
112
+ .header-section p {
113
+ font-size: 0.85rem;
114
+ opacity: 0.7;
115
+ margin: 0;
116
+ }
117
+
118
+ /* Chat takes priority space */
119
+ .chat-area {
120
+ flex-grow: 1;
121
+ }
122
+
123
+ /* Input row */
124
+ .input-row {
125
+ padding-top: 8px;
126
+ }
127
+
128
+ /* Compact buttons */
129
+ .action-buttons {
130
+ display: flex;
131
+ gap: 8px;
132
+ justify-content: center;
133
+ padding: 4px 0;
134
+ }
135
  """
136
 
137
+ # ── Examples ──────────────────────────────────────────────────────
138
  EXAMPLES = [
139
+ ["Help me write a PRD for a mobile mental health check-in feature"],
140
+ ["Score these 3 features using RICE: onboarding revamp, dark mode, referral program"],
141
+ ["Design an A/B test for our new checkout flow"],
142
+ ["What metrics should I track for a community-driven marketplace?"],
143
+ ["Help me draft a stakeholder memo about delaying our launch by 2 weeks"],
 
144
  ]
145
 
146
+ # ��─ Gradio UI ─────────────────────────────────────────────────────
 
 
 
 
147
  with gr.Blocks(title="Agent Ken — PM Copilot") as demo:
148
 
149
+ # Compact header — no long description eating space
150
+ gr.HTML("""
151
+ <div class="header-section">
152
+ <h1>🤖 Agent Ken — PM + Social Impact Copilot</h1>
153
+ <p>Product Manager Copilot with harm-reduction lens · Built on Azure AI Foundry</p>
154
+ </div>
155
+ """)
156
 
157
+ # Chat — main focus, tall
158
  chatbot = gr.Chatbot(
159
  label="Agent Ken",
160
+ height=550,
161
+ placeholder="👋 Hi! I'm Agent Ken — your PM + Social Impact Copilot. Ask me anything about product management, strategy, or inclusive design.",
162
  )
163
 
164
+ # Thread state (invisible)
165
  thread_state = gr.State(value=None)
166
 
167
+ # Input row — textbox + send button side by side
168
+ with gr.Row(elem_classes="input-row"):
169
  msg_input = gr.Textbox(
170
+ placeholder="Type your message here...",
171
+ label="",
172
+ show_label=False,
173
  scale=5,
174
  lines=1,
175
+ max_lines=3,
176
+ container=False,
177
  )
178
+ send_btn = gr.Button("Send 🚀", variant="primary", scale=1, min_width=100)
179
 
180
+ # Action buttons — compact row
181
+ with gr.Row(elem_classes="action-buttons"):
182
+ clear_btn = gr.Button("🗑️ New Conversation", variant="secondary", size="sm")
183
 
184
+ # Examples collapsed, out of the way
185
+ with gr.Accordion("💡 Try an example", open=False):
186
  gr.Examples(
187
  examples=EXAMPLES,
188
  inputs=msg_input,
189
+ label="",
190
  )
191
 
192
+ # Footer
193
+ gr.HTML("""
194
+ <div style="text-align:center; padding:8px 0; font-size:0.75rem; opacity:0.5;">
195
+ Created by Kendrick Filbert · Powered by Azure AI Foundry
196
+ </div>
197
+ """)
198
+
199
+ # ── Events ────────────────────────────────────────────────────
200
  send_btn.click(
201
  fn=respond,
202
  inputs=[msg_input, chatbot, thread_state],
 
216
 
217
  # ── Launch ────────────────────────────────────────────────────────
218
  if __name__ == "__main__":
219
+ demo.launch(server_name="0.0.0.0", server_port=7860, css=CSS, theme=gr.themes.Soft())