Brettapps commited on
Commit
3920eb7
Β·
verified Β·
1 Parent(s): 09ce034

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +92 -205
app.py CHANGED
@@ -19,11 +19,33 @@ if STRIPE_API_KEY:
19
  # Initialize MCP Server
20
  mcp = FastMCP("Aussie Agent Hub")
21
 
22
- # --- MCP TOOLS ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
  @mcp.tool()
25
  def create_stripe_checkout_session(price_id: str, success_url: str, cancel_url: str) -> str:
26
- """Create a Stripe Checkout Session for a given Price ID."""
27
  try:
28
  session = stripe.checkout.Session.create(
29
  payment_method_types=['card'],
@@ -40,282 +62,147 @@ def create_stripe_checkout_session(price_id: str, success_url: str, cancel_url:
40
  def create_stripe_product_with_price(name: str, description: str, unit_amount_cents: int, currency: str = "aud") -> str:
41
  """Create a real Product and Price in Stripe."""
42
  try:
43
- product = stripe.Product.create(
44
- name=name,
45
- description=description,
46
- )
47
- price = stripe.Price.create(
48
- product=product.id,
49
- unit_amount=unit_amount_cents,
50
- currency=currency,
51
- )
52
  return f"Product Created: {name} (ID: {product.id}). Price Created (ID: {price.id}) for {unit_amount_cents/100:.2f} {currency.upper()}."
53
  except Exception as e:
54
  return f"Error creating Stripe product: {str(e)}"
55
 
56
  @mcp.tool()
57
  def generate_ebook(title: str, author: str, chapters: list) -> str:
58
- """Generate EPUB and PDF files from a list of chapters (title and content)."""
59
  epub_path, pdf_path = create_ebook_files(title, author, chapters)
60
- return f"Ebook generated: {epub_path}, {pdf_path}"
61
-
62
- @mcp.tool()
63
- def save_knowledge(module_name: str, content: str) -> str:
64
- """Save knowledge content to the persistent databank."""
65
- success = save_to_databank(f"{module_name}.md", content)
66
- return "Knowledge saved successfully." if success else "Failed to save knowledge."
67
-
68
- @mcp.tool()
69
- def query_databank(filename: str) -> str:
70
- """Retrieve content from the databank."""
71
- content = load_from_databank(filename)
72
- return content if content else "File not found."
73
 
74
  @mcp.tool()
75
  def generate_image(prompt: str) -> str:
76
- """Generate an image using a free ZeroGPU Space via gradio_client, with fallbacks."""
77
  try:
78
  from gradio_client import Client
79
  import shutil
80
-
81
  business_name = os.environ.get("BUSINESS_NAME", "Fair Dinkum Publishing")
82
  owner = os.environ.get("BUSINESS_OWNER", "BRETT SJOBERG")
83
  brand_context = f"Professional brand asset for {business_name} (Owner: {owner}). Style: Modern, clean, high-quality. "
84
  full_prompt = brand_context + prompt
85
 
86
  try:
87
- # Method 1: Gradio Client (ZeroGPU Space - Truly Free)
88
- print(f"Attempting free generation via Gradio Client...")
89
- # Try a very fast, stable space first
90
- try:
91
- client = Client("mrfakename/Z-Image-Turbo", token=HF_TOKEN)
92
- result = client.predict(
93
- prompt=full_prompt,
94
- height=1024,
95
- width=1024,
96
- num_inference_steps=9,
97
- seed=42,
98
- randomize_seed=True,
99
- api_name="/generate_image"
100
- )
101
- temp_image_path = result[0] if isinstance(result, (list, tuple)) else result
102
- model_used = "Z-Image-Turbo (Instant Free)"
103
- except Exception as e1:
104
- print(f"Z-Image-Turbo failed: {e1}. Trying FLUX.1...")
105
- client = Client("black-forest-labs/FLUX.1-schnell", token=HF_TOKEN)
106
- result = client.predict(
107
- prompt=full_prompt,
108
- seed=0,
109
- randomize_seed=True,
110
- width=1024,
111
- height=1024,
112
- num_inference_steps=4,
113
- api_name="/infer"
114
- )
115
- temp_image_path = result[0] if isinstance(result, (list, tuple)) else result
116
- model_used = "FLUX.1-schnell (High-Quality Free)"
117
-
118
- os.makedirs("exports/images", exist_ok=True)
119
- final_path = f"exports/images/{abs(hash(prompt))}.png"
120
- shutil.copy(temp_image_path, final_path)
121
- return f"Branded Image Generated using {model_used}: {final_path}"
122
-
123
- except Exception as g_e:
124
- print(f"Gradio Client method failed: {str(g_e)}. Falling back to classic serverless...")
125
-
126
- # Fallback to Classic Serverless (Method 2)
127
- from huggingface_hub import InferenceClient
128
- hf_client = InferenceClient(provider="hf-inference", token=HF_TOKEN, headers={"x-wait-for-model": "true"})
129
-
130
- models = ["runwayml/stable-diffusion-v1-5", "stabilityai/stable-diffusion-2-1"]
131
- for model_id in models:
132
- try:
133
- image = hf_client.text_to_image(full_prompt, model=model_id)
134
- os.makedirs("exports/images", exist_ok=True)
135
- image_path = f"exports/images/{abs(hash(prompt))}.png"
136
- image.save(image_path)
137
- return f"Branded Image Generated using {model_id} (Free Serverless Tier): {image_path}"
138
- except Exception as e:
139
- continue
140
-
141
- return f"Error: All free generation methods failed. (Gradio Error: {str(g_e)})"
142
-
143
  except Exception as e:
144
- return f"System Error during image generation: {str(e)}"
145
 
146
  @mcp.tool()
147
  def search_market_trends(topic: str) -> str:
148
- """Analyze market trends and competitor activity for a specific topic."""
149
- return f"Market Analysis for '{topic}': High demand identified. Suggested entry price: $19.99."
150
-
151
- @mcp.tool()
152
- def set_business_identity(abn: str, company_name: str, email: str) -> str:
153
- """Set the official business identity for the hub (ABN, Name, Email)."""
154
- data = {"abn": abn, "company_name": company_name, "email": email}
155
- success = save_to_databank("business_identity.json", data, folder="config")
156
- return "Business identity updated successfully." if success else "Failed to update identity."
157
-
158
- @mcp.tool()
159
- def launch_ebook_business(title: str, author: str, topic: str) -> str:
160
- """Automated sequence for ebook business generation."""
161
- chapters = [{"title": "Introduction", "content": f"A guide to {topic}."}]
162
- epub_path, pdf_path = create_ebook_files(title, author, chapters, base_name=title.lower().replace(" ", "_"))
163
- return f"Business Launched: '{title}' created. Files: {epub_path}, {pdf_path}. Ready for launch."
164
-
165
- @mcp.tool()
166
- def calculate_dropshipping_margins(cost_price: float, retail_price: float, shipping_cost: float) -> str:
167
- """Calculate the net profit and ROI for a dropshipping product."""
168
- stripe_fee = (retail_price * 0.029) + 0.30
169
- total_cost = cost_price + shipping_cost + stripe_fee
170
- profit = retail_price - total_cost
171
- roi = (profit / total_cost) * 100
172
- return f"Profit Analysis: Net Profit ${profit:.2f}, ROI {roi:.2f}%. (Stripe fee estimated at ${stripe_fee:.2f})"
173
-
174
- @mcp.tool()
175
- def source_dropshipping_products(niche: str) -> str:
176
- """Source trending dropshipping products in a niche."""
177
- return f"Sourcing for '{niche}': Found 3 high-demand items with reliable shipping to Australia."
178
 
179
  @mcp.tool()
180
  def check_plagiarism(text: str) -> str:
181
- """Check text for potential plagiarism."""
182
- return "Plagiarism Scan: 100% Original. No matches found."
183
-
184
- @mcp.tool()
185
- def calculate_tax_estimate(gross_income: float, expenses: float) -> str:
186
- """Calculate a basic Australian small business tax/GST estimate."""
187
- net_profit = gross_income - expenses
188
- gst_collected = gross_income / 11
189
- return f"Estimate: Net Profit ${net_profit:.2f}. GST to set aside: ${gst_collected:.2f}."
190
-
191
- @mcp.tool()
192
- def analyze_price_war(competitor_prices: list) -> str:
193
- """Analyze competitor prices and suggest an optimal entry point."""
194
- avg = sum(competitor_prices) / len(competitor_prices)
195
- suggested = avg * 0.95
196
- return f"Arbitrage Analysis: Competitor Avg ${avg:.2f}. Suggested Entry Price: ${suggested:.2f}."
197
 
198
  @mcp.tool()
199
  def map_automation_workflow(trigger: str, action: str) -> str:
200
- """Design a logic chain for automating business tasks."""
201
- return f"Workflow Mapped: [Trigger: {trigger}] -> [Agent Action: {action}]."
 
202
 
203
  @mcp.tool()
204
  def draft_dispute_defense(transaction_id: str, reason: str) -> str:
205
- """Generate an evidence package for defending a Stripe dispute."""
206
- return f"Dispute Defense for {transaction_id}: Evidence pack drafted for reason '{reason}'."
207
-
208
- @mcp.tool()
209
- def check_order_status(order_id: str) -> str:
210
- """Check the fulfilment status of an order."""
211
- return f"Status for Order {order_id}: Fulfilled. Digital/Physical tracking active."
212
 
213
  @mcp.tool()
214
  def generate_personalized_response(customer_name: str, issue: str) -> str:
215
- """Generate an empathetic, Aussie-style customer support response."""
216
- return f"G'day {customer_name}, no worries! I've looked into '{issue}' and sorted it for you."
217
-
218
- @mcp.tool()
219
- def create_blogger_post(title: str, content: str, labels: list = None) -> str:
220
- # ... (existing)
221
 
222
  @mcp.tool()
223
- def audit_store_cro(url: str = "Preview Mode") -> str:
224
- """Audit a storefront for Conversion Rate Optimization (CRO) and speed."""
225
- # Simulation of a technical CRO audit
226
- return f"CRO Audit for {url}: Found 3 high-friction points in mobile checkout. Recommendation: Simplify header and enable Stripe Express Checkout."
227
 
228
  @mcp.tool()
229
- def generate_store_layout(niche: str, store_type: str = "Dropshipping") -> str:
230
- """Generate a high-conversion store layout/wireframe draft."""
231
- return f"Store Layout Drafted for '{niche}' ({store_type}): Includes Hero Header, Featured Grid, Social Proof Section, and optimized Product Page."
232
-
233
- @mcp.tool()
234
- def post_to_business_platforms(title: str, content: str, platforms: list) -> str:
235
- # ... (existing)
236
 
237
  @mcp.tool()
238
  def script_to_video_hook(topic: str, product_link: str) -> str:
239
- """Generate a viral video hook and script outline for a product."""
240
- return f"Video Hook for {topic}: [Start with: 'You won't believe how easy it is to...'] -> [Bridge to: {product_link}] -> [CTA: Check out Fair Dinkum Publishing]."
241
-
242
- @mcp.tool()
243
- def generate_ad_copy(platform: str, product_name: str) -> str:
244
- """Draft high-converting ad copy for Meta, Google, or TikTok."""
245
- return f"Ad Copy for {platform}: 'Stop trading time for money. {product_name} is the fair dinkum way to scale. Click to see how!'"
246
 
247
  @mcp.tool()
248
- def estimate_empire_valuation(monthly_profit: float, growth_rate: float) -> str:
249
- # ... (existing)
 
 
250
 
251
  @mcp.tool()
252
  def audit_email_infrastructure(domain: str) -> str:
253
- """Audit DNS records for email deliverability (SPF, DKIM, DMARC)."""
254
- return f"Infrastructure Audit for {domain}: SPF and DKIM configured. DMARC found with p=none. Ready for security hardening."
 
255
 
256
  @mcp.tool()
257
- def draft_automated_sequence(niche: str, goal: str) -> str:
258
- """Draft a multi-step automated email sequence for a specific goal."""
259
- return f"Email Sequence for {niche} ({goal}): [Day 1: Welcome/Value] -> [Day 3: Social Proof] -> [Day 5: The Offer] -> [Day 7: Last Call]."
 
 
 
260
 
261
  # --- AGENT LOGIC (Aussie Domain Router) ---
262
 
263
  def aussie_router(user_input, history):
264
- system_instr = load_from_databank("router_instructions.md") or "You are the Aussie Domain Router. Orchestrate tasks for the user."
265
  messages = [{"role": "system", "content": system_instr}]
266
  for h in history:
267
- if h[0]: messages.append({"role": "user", "content": h[0]})
268
- if h[1]: messages.append({"role": "assistant", "content": h[1]})
269
  messages.append({"role": "user", "content": user_input})
270
 
271
- try:
272
- # Try GPT-4o-mini first
273
- response = client.chat.completions.create(
274
- model="gpt-4o-mini",
275
- messages=messages
276
- )
277
- return response.choices[0].message.content
278
- except Exception as e:
279
- # Fallback to Free Llama 3.1 on Hugging Face (FORCED FREE TIER)
280
- try:
281
- from huggingface_hub import InferenceClient
282
- hf_client = InferenceClient(
283
- provider="hf-inference",
284
- token=HF_TOKEN,
285
- headers={"x-wait-for-model": "true"}
286
- )
287
- response = hf_client.chat_completion(
288
- model="meta-llama/Meta-Llama-3.1-8B-Instruct",
289
- messages=messages,
290
- max_tokens=1000
291
- )
292
- return response.choices[0].message.content
293
- except Exception as hf_e:
294
- return f"Error: Both primary and fallback agents are unavailable. (Details: {str(e)})"
295
 
296
  # --- GRADIO UI ---
297
 
298
  with gr.Blocks(title="Aussie MCP Agent Hub") as demo:
299
  gr.Markdown("# 🐨 Aussie MCP Server Agent Hub")
300
  with gr.Tab("Chat with Hub"):
301
- chatbot = gr.Chatbot()
302
  msg = gr.Textbox(placeholder="Ask your Aussie Agent anything...")
303
  clear = gr.Button("Clear")
304
 
305
  def user(user_message, history):
306
- return "", history + [[user_message, None]]
307
 
308
  def bot(history):
309
- user_message = history[-1][0]
310
  bot_message = aussie_router(user_message, history[:-1])
311
- history[-1][1] = bot_message
312
  return history
313
 
314
- msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
315
- bot, chatbot, chatbot
316
- )
317
  clear.click(lambda: None, None, chatbot, queue=False)
318
 
319
- # Start application
320
  if __name__ == "__main__":
321
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
19
  # Initialize MCP Server
20
  mcp = FastMCP("Aussie Agent Hub")
21
 
22
+ # --- LLM TOOL WORKER (The Intelligence Engine) ---
23
+
24
+ def llm_worker(prompt, system_prompt="You are a specialized business assistant."):
25
+ """Helper to route tool intelligence through OpenAI or Free Fallback."""
26
+ messages = [
27
+ {"role": "system", "content": system_prompt},
28
+ {"role": "user", "content": prompt}
29
+ ]
30
+ try:
31
+ # Try Primary Intelligence (OpenAI)
32
+ response = client.chat.completions.create(model="gpt-4o-mini", messages=messages)
33
+ return response.choices[0].message.content
34
+ except Exception:
35
+ # Fallback to Free Intelligence (Hugging Face Llama 3.1)
36
+ try:
37
+ from huggingface_hub import InferenceClient
38
+ hf_client = InferenceClient(provider="hf-inference", token=HF_TOKEN, headers={"x-wait-for-model": "true"})
39
+ response = hf_client.chat_completion(model="meta-llama/Meta-Llama-3.1-8B-Instruct", messages=messages, max_tokens=1500)
40
+ return response.choices[0].message.content
41
+ except Exception as e:
42
+ return f"Intelligence Error: {str(e)}"
43
+
44
+ # --- REAL MCP TOOLS ---
45
 
46
  @mcp.tool()
47
  def create_stripe_checkout_session(price_id: str, success_url: str, cancel_url: str) -> str:
48
+ """Create a real Stripe Checkout Session for a given Price ID."""
49
  try:
50
  session = stripe.checkout.Session.create(
51
  payment_method_types=['card'],
 
62
  def create_stripe_product_with_price(name: str, description: str, unit_amount_cents: int, currency: str = "aud") -> str:
63
  """Create a real Product and Price in Stripe."""
64
  try:
65
+ product = stripe.Product.create(name=name, description=description)
66
+ price = stripe.Price.create(product=product.id, unit_amount=unit_amount_cents, currency=currency)
 
 
 
 
 
 
 
67
  return f"Product Created: {name} (ID: {product.id}). Price Created (ID: {price.id}) for {unit_amount_cents/100:.2f} {currency.upper()}."
68
  except Exception as e:
69
  return f"Error creating Stripe product: {str(e)}"
70
 
71
  @mcp.tool()
72
  def generate_ebook(title: str, author: str, chapters: list) -> str:
73
+ """Generate professional EPUB and PDF files with branded metadata."""
74
  epub_path, pdf_path = create_ebook_files(title, author, chapters)
75
+ return f"Ebook generated successfully: {epub_path}, {pdf_path}"
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
  @mcp.tool()
78
  def generate_image(prompt: str) -> str:
79
+ """Generate a branded image with multiple free fallbacks."""
80
  try:
81
  from gradio_client import Client
82
  import shutil
 
83
  business_name = os.environ.get("BUSINESS_NAME", "Fair Dinkum Publishing")
84
  owner = os.environ.get("BUSINESS_OWNER", "BRETT SJOBERG")
85
  brand_context = f"Professional brand asset for {business_name} (Owner: {owner}). Style: Modern, clean, high-quality. "
86
  full_prompt = brand_context + prompt
87
 
88
  try:
89
+ client = Client("mrfakename/Z-Image-Turbo", token=HF_TOKEN)
90
+ result = client.predict(prompt=full_prompt, height=1024, width=1024, num_inference_steps=9, seed=42, randomize_seed=True, api_name="/generate_image")
91
+ temp_image_path = result[0] if isinstance(result, (list, tuple)) else result
92
+ model_used = "Z-Image-Turbo"
93
+ except Exception:
94
+ client = Client("black-forest-labs/FLUX.1-schnell", token=HF_TOKEN)
95
+ result = client.predict(prompt=full_prompt, seed=0, randomize_seed=True, width=1024, height=1024, num_inference_steps=4, api_name="/infer")
96
+ temp_image_path = result[0] if isinstance(result, (list, tuple)) else result
97
+ model_used = "FLUX.1-schnell"
98
+
99
+ os.makedirs("exports/images", exist_ok=True)
100
+ final_path = f"exports/images/{abs(hash(prompt))}.png"
101
+ shutil.copy(temp_image_path, final_path)
102
+ return f"Branded Image Generated using {model_used}: {final_path}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  except Exception as e:
104
+ return f"Image Error: {str(e)}"
105
 
106
  @mcp.tool()
107
  def search_market_trends(topic: str) -> str:
108
+ """Deeply analyze market trends, competition, and pricing for any niche."""
109
+ prompt = f"Conduct a professional market research analysis for the niche: '{topic}'. Suggest a pricing strategy and identify potential competitors."
110
+ return llm_worker(prompt, system_prompt="You are an expert Ebook and Dropshipping Market Analyst.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
  @mcp.tool()
113
  def check_plagiarism(text: str) -> str:
114
+ """Audit content for original integrity and potential copyright issues."""
115
+ prompt = f"Perform a deep plagiarism and original integrity audit on the following text. Highlight any sections that seem derivative: \n\n{text}"
116
+ return llm_worker(prompt, system_prompt="You are a professional Content Auditor and Plagiarism Specialist.")
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
  @mcp.tool()
119
  def map_automation_workflow(trigger: str, action: str) -> str:
120
+ """Design a technical logic chain for cross-platform business automation."""
121
+ prompt = f"Design a robust automation workflow for the following: [Trigger: {trigger}] -> [Action: {action}]. Provide technical steps for Zapier or Make.com."
122
+ return llm_worker(prompt, system_prompt="You are a Senior Workflow Integration Architect.")
123
 
124
  @mcp.tool()
125
  def draft_dispute_defense(transaction_id: str, reason: str) -> str:
126
+ """Draft a professional, evidence-backed defense package for a payment dispute."""
127
+ prompt = f"Draft a professional response to a Stripe dispute. Transaction ID: {transaction_id}, Reason: {reason}. Use business identity Fair Dinkum Publishing."
128
+ return llm_worker(prompt, system_prompt="You are a Risk Mitigation and Dispute Specialist.")
 
 
 
 
129
 
130
  @mcp.tool()
131
  def generate_personalized_response(customer_name: str, issue: str) -> str:
132
+ """Create an empathetic, helpful Aussie-style support response."""
133
+ prompt = f"Write a helpful, witty, and empathetic Aussie customer support response for {customer_name} who is experiencing: '{issue}'."
134
+ return llm_worker(prompt, system_prompt="You are a Fair Dinkum Customer Success Agent.")
 
 
 
135
 
136
  @mcp.tool()
137
+ def create_blogger_post(title: str, topic: str) -> str:
138
+ """Draft a full, SEO-optimized blog post for Fair Dinkum Publishing."""
139
+ prompt = f"Draft a comprehensive, SEO-optimized blog post titled '{title}' about the topic '{topic}'. Include clear CTAs and an Aussie flair."
140
+ return llm_worker(prompt, system_prompt="You are a Professional Blogger and SEO Copywriter.")
141
 
142
  @mcp.tool()
143
+ def generate_ad_copy(platform: str, product_name: str) -> str:
144
+ """Draft high-converting ad copy for social media platforms."""
145
+ prompt = f"Draft high-converting, high-CTR ad copy for {platform} promoting the product '{product_name}'. Use psychological triggers and clear CTAs."
146
+ return llm_worker(prompt, system_prompt="You are a Precision Paid Acquisition Expert.")
 
 
 
147
 
148
  @mcp.tool()
149
  def script_to_video_hook(topic: str, product_link: str) -> str:
150
+ """Generate viral video hooks and storyboard outlines for multimedia content."""
151
+ prompt = f"Create 3 viral video hooks and a short storyboard outline for a video about '{topic}'. Mention the link: {product_link}."
152
+ return llm_worker(prompt, system_prompt="You are a Viral Multimedia Strategist.")
 
 
 
 
153
 
154
  @mcp.tool()
155
+ def draft_automated_sequence(niche: str, goal: str) -> str:
156
+ """Draft a multi-step high-conversion email marketing funnel."""
157
+ prompt = f"Draft a 7-day automated email funnel for the niche '{niche}' with the primary goal: '{goal}'. Include subject lines and body copy."
158
+ return llm_worker(prompt, system_prompt="You are a Master Email Marketing Architect.")
159
 
160
  @mcp.tool()
161
  def audit_email_infrastructure(domain: str) -> str:
162
+ """Perform a technical audit of DNS and deliverability infrastructure."""
163
+ prompt = f"Analyze the current email infrastructure for {domain}. Provide recommendations for hardening SPF, DKIM, and DMARC for a Jakarta-based VPS."
164
+ return llm_worker(prompt, system_prompt="You are a Senior Email Deliverability Engineer.")
165
 
166
  @mcp.tool()
167
+ def estimate_empire_valuation(monthly_profit: float, growth_rate: float) -> str:
168
+ """Provide a professional valuation estimate for the digital portfolio."""
169
+ multiple = 24 if growth_rate < 0.05 else 36
170
+ valuation = monthly_profit * multiple
171
+ prompt = f"Provide a detailed strategic rationale for an empire valuation of ${valuation:,.2f} based on ${monthly_profit}/mo profit and {growth_rate*100}% growth."
172
+ return llm_worker(prompt, system_prompt="You are a Portfolio Valuation and Exit Strategist.")
173
 
174
  # --- AGENT LOGIC (Aussie Domain Router) ---
175
 
176
  def aussie_router(user_input, history):
177
+ system_instr = load_from_databank("router_instructions.md") or "You are the Aussie Domain Router."
178
  messages = [{"role": "system", "content": system_instr}]
179
  for h in history:
180
+ if h["role"] == "user": messages.append({"role": "user", "content": h["content"]})
181
+ if h["role"] == "assistant": messages.append({"role": "assistant", "content": h["content"]})
182
  messages.append({"role": "user", "content": user_input})
183
 
184
+ return llm_worker(user_input, system_prompt=system_instr)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
 
186
  # --- GRADIO UI ---
187
 
188
  with gr.Blocks(title="Aussie MCP Agent Hub") as demo:
189
  gr.Markdown("# 🐨 Aussie MCP Server Agent Hub")
190
  with gr.Tab("Chat with Hub"):
191
+ chatbot = gr.Chatbot(type="messages")
192
  msg = gr.Textbox(placeholder="Ask your Aussie Agent anything...")
193
  clear = gr.Button("Clear")
194
 
195
  def user(user_message, history):
196
+ return "", history + [{"role": "user", "content": user_message}]
197
 
198
  def bot(history):
199
+ user_message = history[-1]["content"]
200
  bot_message = aussie_router(user_message, history[:-1])
201
+ history.append({"role": "assistant", "content": bot_message})
202
  return history
203
 
204
+ msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(bot, chatbot, chatbot)
 
 
205
  clear.click(lambda: None, None, chatbot, queue=False)
206
 
 
207
  if __name__ == "__main__":
208
  demo.launch(server_name="0.0.0.0", server_port=7860)