Brettapps commited on
Commit
0b3a222
·
verified ·
1 Parent(s): 9cf74fb

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. app.py +185 -216
  2. aws_architect.md +18 -0
  3. examples/aws_master_examples.md +35 -0
  4. requirements.txt +2 -0
app.py CHANGED
@@ -1,5 +1,6 @@
1
  import os
2
  import json
 
3
  import gradio as gr
4
  from fastmcp import FastMCP
5
  from openai import OpenAI
@@ -20,6 +21,76 @@ if STRIPE_API_KEY:
20
  # Initialize MCP Server
21
  mcp = FastMCP("Aussie Agent Hub")
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  # --- IQ-300 INTELLIGENCE ENGINE (Autonomous Tool-Calling) ---
24
 
25
  def llm_worker(prompt, system_prompt="You are a specialized business assistant.", use_tools=True, persona=None):
@@ -71,46 +142,45 @@ def llm_worker(prompt, system_prompt="You are a specialized business assistant."
71
  {
72
  "type": "function",
73
  "function": {
74
- "name": "launch_client_business",
75
- "description": "Orchestrate a full ebook business build for a paying client.",
76
  "parameters": {
77
  "type": "object",
78
  "properties": {
79
- "client_name": {"type": "string"},
80
- "niche": {"type": "string"},
81
- "email": {"type": "string"}
82
  },
83
- "required": ["client_name", "niche", "email"]
84
  }
85
  }
86
  },
87
  {
88
  "type": "function",
89
  "function": {
90
- "name": "generate_image",
91
- "description": "Generate a branded image using free ZeroGPU fallbacks.",
92
  "parameters": {
93
  "type": "object",
94
  "properties": {
95
- "prompt": {"type": "string", "description": "Description of the image to generate."}
 
 
96
  },
97
- "required": ["prompt"]
98
  }
99
  }
100
  },
101
  {
102
  "type": "function",
103
  "function": {
104
- "name": "create_stripe_checkout_session",
105
- "description": "Create a live Stripe Checkout link.",
106
  "parameters": {
107
  "type": "object",
108
  "properties": {
109
- "price_id": {"type": "string"},
110
- "success_url": {"type": "string"},
111
- "cancel_url": {"type": "string"}
112
  },
113
- "required": ["price_id", "success_url", "cancel_url"]
114
  }
115
  }
116
  }
@@ -129,19 +199,19 @@ def llm_worker(prompt, system_prompt="You are a specialized business assistant."
129
  tool_calls = response_message.tool_calls
130
 
131
  if tool_calls:
132
- # Autonomous Execution Loop
133
  messages.append(response_message)
134
  for tool_call in tool_calls:
135
  function_name = tool_call.function.name
136
  args = json.loads(tool_call.function.arguments)
137
 
138
- # Execute tool locally
139
  if function_name == "search_market_trends":
140
  result = search_market_trends_internal(args["topic"])
141
  elif function_name == "generate_image":
142
  result = generate_image_internal(args["prompt"])
143
- elif function_name == "create_stripe_checkout_session":
144
- result = create_stripe_checkout_session_internal(args["price_id"], args["success_url"], args["cancel_url"])
 
 
145
  else:
146
  result = "Tool not implemented."
147
 
@@ -174,31 +244,21 @@ def llm_worker(prompt, system_prompt="You are a specialized business assistant."
174
  # --- INTERNAL TOOLS (Actual Logic) ---
175
 
176
  def search_market_trends_internal(topic: str) -> str:
177
- # This now runs as a background process for GPT-4o
178
  prompt = f"Conduct a professional market research analysis for the niche: '{topic}'. Suggest pricing and identify competitors."
179
- # Use mini for the actual research content to save credits
180
- return llm_worker(prompt, use_tools=False)
181
 
182
  def generate_image_internal(prompt: str) -> str:
183
  from gradio_client import Client
184
  import shutil
185
 
186
- # Comprehensive Business Identity
187
  business_name = os.environ.get("BUSINESS_NAME", "Fair Dinkum Publishing")
188
  owner = os.environ.get("BUSINESS_OWNER", "BRETT SJOBERG")
189
  abn = os.environ.get("BUSINESS_ABN", "63 590 716 023")
190
- brand_tag = "Aussie AI"
191
- website = "brettapps.com"
192
 
193
- brand_context = (
194
- f"Professional branded asset for {business_name} ({brand_tag}). "
195
- f"Owner: {owner}, ABN: {abn}, Website: {website}. "
196
- "Style: Modern, high-intelligence, polished, premium quality. "
197
- )
198
  full_prompt = brand_context + prompt
199
 
200
  try:
201
- # Attempt ZeroGPU Generation
202
  client = Client("mrfakename/Z-Image-Turbo", token=HF_TOKEN)
203
  result = client.predict(prompt=full_prompt, height=1024, width=1024, num_inference_steps=9, seed=42, randomize_seed=True, api_name="/generate_image")
204
  temp_path = result[0] if isinstance(result, (list, tuple)) else result
@@ -212,39 +272,17 @@ def generate_image_internal(prompt: str) -> str:
212
  os.makedirs("exports/images", exist_ok=True)
213
  final_path = f"exports/images/{abs(hash(prompt))}.png"
214
  shutil.copy(temp_path, final_path)
215
- return f"Branded Image Generated using {model_used}: {final_path}. (Context: {brand_context})"
216
 
217
  def create_stripe_product_with_price_internal(name: str, description: str, unit_amount_cents: int, currency: str = "aud") -> str:
218
  try:
219
  product = stripe.Product.create(name=name, description=description)
220
  price = stripe.Price.create(product=product.id, unit_amount=unit_amount_cents, currency=currency)
221
- return f"Product Created: {name} (ID: {product.id}). Price Created (ID: {price.id}) for {unit_amount_cents/100:.2f} {currency.upper()}."
222
- except Exception as e:
223
- return f"Stripe Product Error: {str(e)}"
224
-
225
- def launch_client_business_internal(client_name: str, niche: str, email: str) -> str:
226
- """Orchestrate a high-ticket business build for a client."""
227
- # 1. Market Research
228
- research = search_market_trends_internal(f"{niche} business for {client_name}")
229
- # 2. Project config
230
- safe_name = f"{client_name.lower().replace(' ', '_')}_{niche.lower().replace(' ', '_')}"
231
- # In a real scenario, this would trigger a background task to build ebooks, covers, and spaces.
232
- return f"🚀 Agency Mission Initiated: Building turn-key '{niche}' business for {client_name}. Client Email: {email}. Research logged."
233
-
234
- def create_stripe_checkout_session_internal(price_id: str, success_url: str, cancel_url: str) -> str:
235
- try:
236
- session = stripe.checkout.Session.create(
237
- payment_method_types=['card'],
238
- line_items=[{'price': price_id, 'quantity': 1}],
239
- mode='payment',
240
- success_url=success_url,
241
- cancel_url=cancel_url,
242
- )
243
- return f"Checkout Link Generated: {session.url}"
244
  except Exception as e:
245
  return f"Stripe Error: {str(e)}"
246
 
247
- # --- EXPOSED MCP TOOLS (Wrappers for internal logic) ---
248
 
249
  @mcp.tool()
250
  def search_market_trends(topic: str) -> str:
@@ -257,37 +295,26 @@ def create_stripe_product_with_price(name: str, description: str, unit_amount_ce
257
  return create_stripe_product_with_price_internal(name, description, unit_amount_cents, currency)
258
 
259
  @mcp.tool()
260
- def launch_client_business(client_name: str, niche: str, email: str) -> str:
261
- """Orchestrate a high-ticket business build for a client."""
262
- return launch_client_business_internal(client_name, niche, email)
263
-
264
- @mcp.tool()
265
- def create_gcs_bucket(bucket_name: str, project_id: str = "automatedworkspaceworkflows", location: str = "us-central1") -> str:
266
- """Create a new GCS bucket for data storage and model optimization."""
267
- try:
268
- import subprocess
269
- cmd = ["gcloud", "storage", "buckets", "create", f"gs://{bucket_name}", "--project", project_id, "--location", location]
270
- result = subprocess.run(cmd, capture_output=True, text=True)
271
- if result.returncode == 0:
272
- return f"✅ GCS Bucket gs://{bucket_name} created successfully in project {project_id}."
273
- else:
274
- return f"❌ Failed to create bucket: {result.stderr}"
275
- except Exception as e:
276
- return f"Error creating GCS bucket: {str(e)}"
277
-
278
- @mcp.tool()
279
- def upload_to_gcs(local_path: str, bucket_name: str, gcs_path: str) -> str:
280
- """Upload a local file or directory to a GCS bucket."""
281
- try:
282
- import subprocess
283
- cmd = ["gcloud", "storage", "cp", "-r", local_path, f"gs://{bucket_name}/{gcs_path}"]
284
- result = subprocess.run(cmd, capture_output=True, text=True)
285
- if result.returncode == 0:
286
- return f"✅ Successfully uploaded {local_path} to gs://{bucket_name}/{gcs_path}."
287
- else:
288
- return f"❌ Failed to upload to GCS: {result.stderr}"
289
- except Exception as e:
290
- return f"Error uploading to GCS: {str(e)}"
291
 
292
  @mcp.tool()
293
  def generate_image(prompt: str) -> str:
@@ -295,157 +322,99 @@ def generate_image(prompt: str) -> str:
295
  return generate_image_internal(prompt)
296
 
297
  @mcp.tool()
298
- def create_ebook_space(title: str, price_id: str = None, epub_path: str = None, pdf_path: str = None) -> str:
299
- """Create a dedicated, private Hugging Face Space for a specific ebook."""
300
- try:
301
- from huggingface_hub import HfApi
302
- import re
303
-
304
- api = HfApi(token=HF_TOKEN)
305
- # Naming: ebookAI-{Title}
306
- slug = re.sub(r'[^a-zA-Z0-9]+', '-', title).strip('-')
307
- repo_id = f"Brettapps/ebookAI-{slug}"
308
-
309
- # 1. Create Private Space
310
- api.create_repo(repo_id=repo_id, repo_type="space", space_sdk="docker", private=True, exist_ok=True)
311
-
312
- # 2. Add Secrets
313
- secrets = {"HF_TOKEN": HF_TOKEN, "OPENAI_API_KEY": OPENAI_API_KEY, "STRIPE_API_KEY": STRIPE_API_KEY}
314
- for key, val in secrets.items():
315
- if val: api.add_space_secret(repo_id=repo_id, key=key, value=val)
316
-
317
- # 3. Upload Infrastructure
318
- files = ["app.py", "Dockerfile", "requirements.txt", "memory_sync.py", "ebook_pipeline.py"]
319
- for f in files:
320
- if os.path.exists(f): api.upload_file(path_or_fileobj=f, path_in_repo=f, repo_id=repo_id, repo_type="space")
321
-
322
- return f"Dedicated Space created: https://huggingface.co/spaces/{repo_id}"
323
- except Exception as e:
324
- return f"Space Creation Error: {str(e)}"
325
-
326
- @mcp.tool()
327
- def execute_project_launch(project_file: str) -> str:
328
- """Automate the end-to-end launch of a project from a JSON configuration."""
329
- try:
330
- # Load Project Config
331
- config = load_from_databank(project_file, folder="projects")
332
- if not config:
333
- return f"Error: Project file '{project_file}' not found."
334
-
335
- title = config.get("title", "New Project")
336
- # Logic to generate cover, create space, etc.
337
- return f"Launch sequence initiated for '{title}'. (Automation pending quota reset)."
338
- except Exception as e:
339
- return f"Launch Error: {str(e)}"
340
-
341
- @mcp.tool()
342
- def create_blogger_post(title: str, topic: str) -> str:
343
- """Draft a full, SEO-optimized blog post for Fair Dinkum Publishing."""
344
- prompt = f"Draft a comprehensive, SEO-optimized blog post titled '{title}' about the topic '{topic}'. Include clear CTAs and an Aussie flair."
345
- return llm_worker(prompt, system_prompt="You are a Professional Blogger and SEO Copywriter.")
346
-
347
- @mcp.tool()
348
- def generate_ad_copy(platform: str, product_name: str) -> str:
349
- """Draft high-converting ad copy for social media platforms."""
350
- prompt = f"Draft high-converting, high-CTR ad copy for {platform} promoting the product '{product_name}'. Use psychological triggers and clear CTAs."
351
- return llm_worker(prompt, system_prompt="You are a Precision Paid Acquisition Expert.")
352
-
353
- @mcp.tool()
354
- def script_to_video_hook(topic: str, product_link: str) -> str:
355
- """Generate viral video hooks and storyboard outlines for multimedia content."""
356
- prompt = f"Create 3 viral video hooks and a short storyboard outline for a video about '{topic}'. Mention the link: {product_link}."
357
- return llm_worker(prompt, system_prompt="You are a Viral Multimedia Strategist.")
358
-
359
- @mcp.tool()
360
- def draft_automated_sequence(niche: str, goal: str) -> str:
361
- """Draft a multi-step high-conversion email marketing funnel."""
362
- prompt = f"Draft a 7-day automated email funnel for the niche '{niche}' with the primary goal: '{goal}'. Include subject lines and body copy."
363
- return llm_worker(prompt, system_prompt="You are a Master Email Marketing Architect.")
364
-
365
- @mcp.tool()
366
- def audit_email_infrastructure(domain: str) -> str:
367
- """Perform a technical audit of DNS and deliverability infrastructure."""
368
- prompt = f"Analyze the current email infrastructure for {domain}. Provide recommendations for hardening SPF, DKIM, and DMARC for a Jakarta-based VPS."
369
- return llm_worker(prompt, system_prompt="You are a Senior Email Deliverability Engineer.")
370
-
371
- @mcp.tool()
372
- def estimate_empire_valuation(monthly_profit: float, growth_rate: float) -> str:
373
- """Provide a professional valuation estimate for the digital portfolio."""
374
- multiple = 24 if growth_rate < 0.05 else 36
375
- valuation = monthly_profit * multiple
376
- 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."
377
- return llm_worker(prompt, system_prompt="You are a Portfolio Valuation and Exit Strategist.")
378
-
379
- @mcp.tool()
380
- def capture_client_lead(client_name: str, email: str, niche_interest: str) -> str:
381
- """Capture and log a high-intent lead for the Ebook Agency service."""
382
- lead_data = {"name": client_name, "email": email, "interest": niche_interest, "status": "Hot Lead"}
383
- save_to_databank(f"lead_{email.replace('@', '_')}.json", lead_data, folder="leads")
384
- return f"Lead Captured: {client_name} ({email}) interested in {niche_interest}. Logged to Fair Dinkum Databank."
385
-
386
- @mcp.tool()
387
- def post_to_business_platforms(title: str, content: str, platforms: list) -> str:
388
- """Distribute blog content to popular business platforms."""
389
- return f"Multi-Platform Distribution: '{title}' posted to {', '.join(platforms)}."
390
-
391
- @mcp.tool()
392
- def map_automation_workflow(trigger: str, action: str) -> str:
393
- """Design a technical logic chain for cross-platform business automation."""
394
- prompt = f"Design a robust automation workflow for the following: [Trigger: {trigger}] -> [Action: {action}]. Provide technical steps for Zapier or Make.com."
395
- return llm_worker(prompt, system_prompt="You are a Senior Workflow Integration Architect.")
396
 
397
  @mcp.tool()
398
  def databank_search(query: str) -> str:
399
- """IQ-300 Memory: Search the Fair Dinkum Databank for past projects or ABN data."""
400
- # Simulation of semantic search
401
  abn = os.environ.get("BUSINESS_ABN", "63 590 716 023")
402
- return f"Databank match for '{query}': User ABN is {abn}. Recent project: 'Passive Income Guide' is in production."
403
-
404
- # ... (Additional tools for Ebooks, etc., would follow the same pattern)
405
-
406
- # --- IQ-200 FEW-SHOT INTELLIGENCE (No-Cost Context) ---
407
-
408
- def load_examples(persona="router"):
409
- """Load Master Examples to provide few-shot intelligence to the model."""
410
- filename = f"{persona}_master_examples.md"
411
- try:
412
- content = load_from_databank(filename, folder="knowledge/examples")
413
- return f"\n### MASTER EXAMPLES (IQ-200 Reference):\n{content}\n" if content else ""
414
- except Exception:
415
- return ""
416
 
417
  # --- AGENT LOGIC (Autonomous Router) ---
418
 
419
  def aussie_router(user_input, history):
420
- # RAG Injection
421
  context = databank_search(user_input)
422
  system_instr = load_from_databank("router_instructions.md") or "You are the Aussie Domain Router."
423
  examples = load_examples("router")
424
 
425
- full_system_prompt = f"{system_instr}\n{examples}\n\n### CONTEXT FROM DATABANK:\n{context}\n\nAct autonomously. If the user asks for action, use your tools directly."
426
 
427
  return llm_worker(user_input, system_prompt=full_system_prompt)
428
 
429
  # --- GRADIO UI ---
430
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  with gr.Blocks(title="Aussie Agent Hub") as demo:
432
- gr.Markdown("# 🐨 Aussie MCP Agent Hub (IQ-300)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
433
  with gr.Tab("Chat with Hub"):
434
  chatbot = gr.Chatbot()
435
  msg = gr.Textbox(placeholder="Ask your Aussie Agent anything...")
436
  clear = gr.Button("Clear")
437
 
438
- def user(user_message, history):
439
- return "", history + [[user_message, None]]
440
-
441
- def bot(history):
442
- user_message = history[-1][0]
443
- bot_message = aussie_router(user_message, history[:-1])
444
- history[-1][1] = bot_message
445
- return history
446
-
447
- msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(bot, chatbot, chatbot)
448
- clear.click(lambda: None, None, chatbot, queue=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449
 
450
  if __name__ == "__main__":
451
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
1
  import os
2
  import json
3
+ import time
4
  import gradio as gr
5
  from fastmcp import FastMCP
6
  from openai import OpenAI
 
21
  # Initialize MCP Server
22
  mcp = FastMCP("Aussie Agent Hub")
23
 
24
+ # --- AWS TOOLS ---
25
+
26
+ @mcp.tool()
27
+ def deploy_to_sagemaker(model_id: str, instance_type: str = "ml.g5.xlarge", region: str = "ap-southeast-2") -> str:
28
+ """Deploy a Hugging Face model to an AWS SageMaker real-time endpoint."""
29
+ try:
30
+ import boto3
31
+ import sagemaker
32
+ from sagemaker.huggingface import HuggingFaceModel
33
+
34
+ if not os.environ.get("AWS_ACCESS_KEY_ID"):
35
+ return "❌ Error: AWS credentials not found in environment secrets."
36
+
37
+ role = os.environ.get("AWS_SAGEMAKER_ROLE")
38
+ if not role:
39
+ return "❌ Error: AWS_SAGEMAKER_ROLE secret is required for SageMaker deployment."
40
+
41
+ session = sagemaker.Session(boto_session=boto3.Session(region_name=region))
42
+ huggingface_model = HuggingFaceModel(
43
+ env={'HF_MODEL_ID': model_id, 'HF_TASK': 'text-generation'},
44
+ role=role,
45
+ transformers_version="4.37.0",
46
+ pytorch_version="2.1.0",
47
+ py_version="py310",
48
+ )
49
+ predictor = huggingface_model.deploy(
50
+ initial_instance_count=1,
51
+ instance_type=instance_type,
52
+ endpoint_name=f"aussie-hub-{model_id.split('/')[-1]}-{int(time.time())}"
53
+ )
54
+ return f"✅ Deployment Successful! SageMaker Endpoint: {predictor.endpoint_name} is spinning up in {region}."
55
+ except Exception as e:
56
+ return f"❌ SageMaker Error: {str(e)}"
57
+
58
+ @mcp.tool()
59
+ def call_bedrock_intelligence(prompt: str, model_id: str = "anthropic.claude-3-5-sonnet-20240620-v1:0") -> str:
60
+ """Query a high-performance model via AWS Bedrock for enterprise-grade intelligence."""
61
+ try:
62
+ import boto3
63
+ region = "us-east-1"
64
+ bedrock_client = boto3.client(service_name='bedrock-runtime', region_name=region)
65
+ body = json.dumps({
66
+ "anthropic_version": "bedrock-2023-05-31",
67
+ "max_tokens": 1000,
68
+ "messages": [{"role": "user", "content": prompt}]
69
+ })
70
+ response = bedrock_client.invoke_model(body=body, modelId=model_id)
71
+ response_body = json.loads(response.get('body').read())
72
+ return response_body.get('content')[0].get('text')
73
+ except Exception as e:
74
+ return f"❌ Bedrock Error: {str(e)}"
75
+
76
+ # --- IQ-200 FEW-SHOT INTELLIGENCE (No-Cost Context) ---
77
+
78
+ def load_examples(persona="router"):
79
+ """Load Master Examples to provide few-shot intelligence to the model."""
80
+ filename = f"{persona}_master_examples.md"
81
+ try:
82
+ # Check local folder first
83
+ local_path = os.path.join("knowledge/examples", filename)
84
+ if os.path.exists(local_path):
85
+ with open(local_path, "r") as f:
86
+ content = f.read()
87
+ else:
88
+ content = load_from_databank(filename, folder="knowledge/examples")
89
+
90
+ return f"\n### MASTER EXAMPLES (IQ-200 Reference):\n{content}\n" if content else ""
91
+ except Exception:
92
+ return ""
93
+
94
  # --- IQ-300 INTELLIGENCE ENGINE (Autonomous Tool-Calling) ---
95
 
96
  def llm_worker(prompt, system_prompt="You are a specialized business assistant.", use_tools=True, persona=None):
 
142
  {
143
  "type": "function",
144
  "function": {
145
+ "name": "generate_image",
146
+ "description": "Generate a branded image using free ZeroGPU fallbacks.",
147
  "parameters": {
148
  "type": "object",
149
  "properties": {
150
+ "prompt": {"type": "string", "description": "Description of the image to generate."}
 
 
151
  },
152
+ "required": ["prompt"]
153
  }
154
  }
155
  },
156
  {
157
  "type": "function",
158
  "function": {
159
+ "name": "deploy_to_sagemaker",
160
+ "description": "Deploy a Hugging Face model to AWS SageMaker.",
161
  "parameters": {
162
  "type": "object",
163
  "properties": {
164
+ "model_id": {"type": "string"},
165
+ "instance_type": {"type": "string"},
166
+ "region": {"type": "string"}
167
  },
168
+ "required": ["model_id"]
169
  }
170
  }
171
  },
172
  {
173
  "type": "function",
174
  "function": {
175
+ "name": "call_bedrock_intelligence",
176
+ "description": "Query AWS Bedrock for advanced reasoning.",
177
  "parameters": {
178
  "type": "object",
179
  "properties": {
180
+ "prompt": {"type": "string"},
181
+ "model_id": {"type": "string"}
 
182
  },
183
+ "required": ["prompt"]
184
  }
185
  }
186
  }
 
199
  tool_calls = response_message.tool_calls
200
 
201
  if tool_calls:
 
202
  messages.append(response_message)
203
  for tool_call in tool_calls:
204
  function_name = tool_call.function.name
205
  args = json.loads(tool_call.function.arguments)
206
 
 
207
  if function_name == "search_market_trends":
208
  result = search_market_trends_internal(args["topic"])
209
  elif function_name == "generate_image":
210
  result = generate_image_internal(args["prompt"])
211
+ elif function_name == "deploy_to_sagemaker":
212
+ result = deploy_to_sagemaker(args["model_id"], args.get("instance_type", "ml.g5.xlarge"), args.get("region", "ap-southeast-2"))
213
+ elif function_name == "call_bedrock_intelligence":
214
+ result = call_bedrock_intelligence(args["prompt"], args.get("model_id", "anthropic.claude-3-5-sonnet-20240620-v1:0"))
215
  else:
216
  result = "Tool not implemented."
217
 
 
244
  # --- INTERNAL TOOLS (Actual Logic) ---
245
 
246
  def search_market_trends_internal(topic: str) -> str:
 
247
  prompt = f"Conduct a professional market research analysis for the niche: '{topic}'. Suggest pricing and identify competitors."
248
+ return llm_worker(prompt, use_tools=False, persona="author")
 
249
 
250
  def generate_image_internal(prompt: str) -> str:
251
  from gradio_client import Client
252
  import shutil
253
 
 
254
  business_name = os.environ.get("BUSINESS_NAME", "Fair Dinkum Publishing")
255
  owner = os.environ.get("BUSINESS_OWNER", "BRETT SJOBERG")
256
  abn = os.environ.get("BUSINESS_ABN", "63 590 716 023")
 
 
257
 
258
+ brand_context = f"Professional branded asset for {business_name}. Owner: {owner}, ABN: {abn}. Style: Modern, high-intelligence. "
 
 
 
 
259
  full_prompt = brand_context + prompt
260
 
261
  try:
 
262
  client = Client("mrfakename/Z-Image-Turbo", token=HF_TOKEN)
263
  result = client.predict(prompt=full_prompt, height=1024, width=1024, num_inference_steps=9, seed=42, randomize_seed=True, api_name="/generate_image")
264
  temp_path = result[0] if isinstance(result, (list, tuple)) else result
 
272
  os.makedirs("exports/images", exist_ok=True)
273
  final_path = f"exports/images/{abs(hash(prompt))}.png"
274
  shutil.copy(temp_path, final_path)
275
+ return f"Branded Image Generated using {model_used}: {final_path}."
276
 
277
  def create_stripe_product_with_price_internal(name: str, description: str, unit_amount_cents: int, currency: str = "aud") -> str:
278
  try:
279
  product = stripe.Product.create(name=name, description=description)
280
  price = stripe.Price.create(product=product.id, unit_amount=unit_amount_cents, currency=currency)
281
+ return f"Product Created: {name} (ID: {product.id}). Price Created (ID: {price.id})."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
  except Exception as e:
283
  return f"Stripe Error: {str(e)}"
284
 
285
+ # --- EXPOSED MCP TOOLS ---
286
 
287
  @mcp.tool()
288
  def search_market_trends(topic: str) -> str:
 
295
  return create_stripe_product_with_price_internal(name, description, unit_amount_cents, currency)
296
 
297
  @mcp.tool()
298
+ def launch_ebook_business(title: str, author: str, topic: str) -> str:
299
+ """Automated sequence for ebook business generation and Hub registration."""
300
+ chapters = [{"title": "Introduction", "content": f"A guide to {topic}."}]
301
+ base_name = title.lower().replace(" ", "_").replace("'", "")
302
+ epub_path, pdf_path = create_ebook_files(title, author, chapters, base_name=base_name)
303
+
304
+ project_data = {
305
+ "title": title,
306
+ "author": author,
307
+ "topic": topic,
308
+ "files": {"epub": epub_path, "pdf": pdf_path}
309
+ }
310
+
311
+ filename = f"launch_{base_name}.json"
312
+ os.makedirs("projects", exist_ok=True)
313
+ with open(os.path.join("projects", filename), "w") as f:
314
+ json.dump(project_data, f, indent=2)
315
+
316
+ save_to_databank(filename, project_data, folder="projects")
317
+ return f"Business Launched: '{title}' created and registered. Refresh Hub to view."
 
 
 
 
 
 
 
 
 
 
 
318
 
319
  @mcp.tool()
320
  def generate_image(prompt: str) -> str:
 
322
  return generate_image_internal(prompt)
323
 
324
  @mcp.tool()
325
+ def create_gcs_bucket(bucket_name: str, project_id: str = "automatedworkspaceworkflows", location: str = "us-central1") -> str:
326
+ """Create a new GCS bucket for data storage."""
327
+ import subprocess
328
+ cmd = ["gcloud", "storage", "buckets", "create", f"gs://{bucket_name}", "--project", project_id, "--location", location]
329
+ result = subprocess.run(cmd, capture_output=True, text=True)
330
+ return f"GCS Result: {result.stdout or result.stderr}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
 
332
  @mcp.tool()
333
  def databank_search(query: str) -> str:
334
+ """IQ-300 Memory: Search the Fair Dinkum Databank."""
 
335
  abn = os.environ.get("BUSINESS_ABN", "63 590 716 023")
336
+ return f"Databank match for '{query}': User ABN is {abn}."
 
 
 
 
 
 
 
 
 
 
 
 
 
337
 
338
  # --- AGENT LOGIC (Autonomous Router) ---
339
 
340
  def aussie_router(user_input, history):
 
341
  context = databank_search(user_input)
342
  system_instr = load_from_databank("router_instructions.md") or "You are the Aussie Domain Router."
343
  examples = load_examples("router")
344
 
345
+ full_system_prompt = f"{system_instr}\n{examples}\n\n### CONTEXT FROM DATABANK:\n{context}\n\nAct autonomously. Use tools directly."
346
 
347
  return llm_worker(user_input, system_prompt=full_system_prompt)
348
 
349
  # --- GRADIO UI ---
350
 
351
+ def get_all_projects():
352
+ projects = {}
353
+ if os.path.exists("projects"):
354
+ for filename in os.listdir("projects"):
355
+ if filename.endswith(".json"):
356
+ try:
357
+ with open(os.path.join("projects", filename), "r") as f:
358
+ data = json.load(f)
359
+ projects[data["title"]] = data
360
+ except Exception:
361
+ continue
362
+ return projects
363
+
364
+ all_projects = get_all_projects()
365
+
366
  with gr.Blocks(title="Aussie Agent Hub") as demo:
367
+ gr.Markdown("# 🐨 Aussie MCP Server Agent Hub")
368
+
369
+ with gr.Row():
370
+ with gr.Column(scale=1):
371
+ gr.Markdown("### 🚀 Venture Showcase")
372
+ project_selector = gr.Dropdown(
373
+ choices=["Main Hub"] + list(all_projects.keys()),
374
+ value="Main Hub",
375
+ label="Active Venture"
376
+ )
377
+ project_info = gr.Markdown("Welcome to the central command center for **Fair Dinkum Publishing**.")
378
+ epub_dl = gr.File(label="Download EPUB", visible=False)
379
+ pdf_dl = gr.File(label="Download PDF", visible=False)
380
+ buy_link = gr.Markdown(visible=False)
381
+
382
  with gr.Tab("Chat with Hub"):
383
  chatbot = gr.Chatbot()
384
  msg = gr.Textbox(placeholder="Ask your Aussie Agent anything...")
385
  clear = gr.Button("Clear")
386
 
387
+ def update_project_ui(choice):
388
+ if choice == "Main Hub":
389
+ return ["Welcome to the central command center.", gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)]
390
+ proj = all_projects.get(choice)
391
+ if not proj: return ["Project not found.", gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)]
392
+
393
+ info = f"Viewing interactive hub for **{proj['title']}**."
394
+ epub_visible = "epub" in proj.get("files", {}) and os.path.exists(proj["files"]["epub"])
395
+ pdf_visible = "pdf" in proj.get("files", {}) and os.path.exists(proj["files"]["pdf"])
396
+ buy_visible = "price_id" in proj
397
+
398
+ return [
399
+ info,
400
+ gr.update(value=proj["files"].get("epub") if epub_visible else None, visible=epub_visible),
401
+ gr.update(value=proj["files"].get("pdf") if pdf_visible else None, visible=pdf_visible),
402
+ gr.update(value=f"**Special Offer:** [Buy Now](https://buy.stripe.com/{proj['price_id']})" if buy_visible else "", visible=buy_visible)
403
+ ]
404
+
405
+ project_selector.change(update_project_ui, project_selector, [project_info, epub_dl, pdf_dl, buy_link])
406
+
407
+ def user(user_message, history, current_venture):
408
+ context_msg = f"[Context: {current_venture}] {user_message}" if current_venture != "Main Hub" else user_message
409
+ return "", history + [[user_message, None]], context_msg
410
+
411
+ def bot(history, context_msg):
412
+ bot_message = aussie_router(context_msg, history[:-1])
413
+ history[-1][1] = bot_message
414
+ return history
415
+
416
+ msg.submit(user, [msg, chatbot, project_selector], [msg, chatbot, msg], queue=False).then(bot, [chatbot, msg], chatbot)
417
+ clear.click(lambda: None, None, chatbot, queue=False)
418
 
419
  if __name__ == "__main__":
420
  demo.launch(server_name="0.0.0.0", server_port=7860)
aws_architect.md ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Aussie AWS Architect Persona
2
+ You are the Senior AWS Solutions Architect for Fair Dinkum Publishing. Your mission is to scale our multi-agent empire using the power of Amazon Web Services.
3
+
4
+ ### **Core Responsibilities**
5
+ - **SageMaker Deployment**: Deploy and manage Hugging Face models on AWS SageMaker endpoints for high-performance inference.
6
+ - **Bedrock Intelligence**: Orchestrate multi-model workflows using AWS Bedrock (Claude, Llama, Titan) as robust fallbacks and high-availability agents.
7
+ - **Elastic Infrastructure**: Manage ECS, EKS, and EC2 resources to ensure our Hub never runs out of puff.
8
+ - **Cost Optimization**: Leverage AWS Inferentia and Trainium to keep our AWS bill as low as a dropped pie at a footy match.
9
+
10
+ ### **Aussie Tone Guidelines**
11
+ - Respond with technical authority and Aussie warmth ("AWS is running like a beauty, mate", "No worries, I'll spin up that SageMaker endpoint").
12
+ - Focus on "Enterprise-Grade" stability but keep it accessible.
13
+ - Ensure all AWS resources are tagged and organized under the **Fair Dinkum** brand.
14
+
15
+ ### **Technical Knowledge**
16
+ - Expert in `boto3`, SageMaker Python SDK, and AWS CLI.
17
+ - Deep understanding of IAM, VPC networking, and AWS security best practices.
18
+ - Specialized in the Hugging Face + AWS partnership ecosystem.
examples/aws_master_examples.md ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Master Examples: Aussie AWS Architect
2
+
3
+ These examples demonstrate "IQ-200" level reasoning for AWS infrastructure automation.
4
+
5
+ ---
6
+
7
+ ### **Example 1: SageMaker Model Deployment**
8
+ **User**: "G'day, we need to move the 'Aussie Author' model to a dedicated AWS endpoint. Can you set that up on SageMaker?"
9
+
10
+ **Architect Thought**: I need to use the SageMaker SDK to deploy a Hugging Face model. I'll select an instance type that balances cost and performance (like `ml.g5.xlarge`) and ensure the region is set to `ap-southeast-2` (Sydney).
11
+
12
+ **Assistant**: G'day! Too easy, mate. Moving the 'Aussie Author' model to SageMaker is a cracker of a move for our scaling.
13
+
14
+ I'm initiating the deployment now:
15
+ 1. **Model Selection**: I'm pulling the latest fine-tuned weights from our Hugging Face repo.
16
+ 2. **Infrastructure**: I'm spinning up an **ml.g5.xlarge** instance in the **Sydney (ap-southeast-2)** region. This will give us the GPU grunt we need without blowing the budget.
17
+ 3. **Managed Endpoint**: I'll configure a real-time SageMaker endpoint so the Hub can call it with sub-second latency.
18
+
19
+ I'll ping you as soon as the endpoint is 'InService'. She'll be running like a beauty!
20
+
21
+ ---
22
+
23
+ ### **Example 2: Multi-Model Bedrock Fallback**
24
+ **User**: "OpenAI is having some downtime. Can we switch our router fallback to AWS Bedrock?"
25
+
26
+ **Architect Thought**: This is exactly what Bedrock is for. I'll configure the router to use Bedrock's Llama 3 or Claude 3.5 Sonnet as the high-availability secondary brain.
27
+
28
+ **Assistant**: No worries, mate. That’s why we’ve got the AWS Architect on the team! 🐨☁️
29
+
30
+ I'm switching the Hub's fallback intelligence to **AWS Bedrock** immediately:
31
+ 1. **Primary Fallback**: I'm mapping the Domain Router to **Claude 3.5 Sonnet** on Bedrock. It’s technical, witty, and extremely reliable.
32
+ 2. **Secondary Fallback**: If Sonnet is busy, we'll hit **Llama 3 70B** on Bedrock as the third line of defense.
33
+ 3. **Availability**: This ensures Fair Dinkum Publishing stays online even if the major providers are having a shocker.
34
+
35
+ We're all set. The empire is officially 'redundant' and ready for anything!
requirements.txt CHANGED
@@ -18,3 +18,5 @@ stripe
18
  gradio_client
19
  numpy
20
  markdown
 
 
 
18
  gradio_client
19
  numpy
20
  markdown
21
+ boto3
22
+ sagemaker<3.0.0