Spaces:
Sleeping
Sleeping
from smolagents import ( | |
load_tool, | |
CodeAgent, | |
ToolCallingAgent, | |
InferenceClientModel, | |
LiteLLMModel, | |
OpenAIServerModel, | |
GradioUI, | |
MCPClient | |
) | |
from mcp import StdioServerParameters | |
import os | |
from dotenv import load_dotenv | |
import gradio as gr | |
load_dotenv() | |
kgb_server_parameters = StdioServerParameters( | |
command="npx", | |
args=[ | |
"mcp-remote", | |
"https://agents-mcp-hackathon-kgb-mcp.hf.space/gradio_api/mcp/sse", | |
"--transport", | |
"sse-only"], | |
) | |
T2I_server_parameters = StdioServerParameters( | |
command="npx", | |
args=[ | |
"mcp-remote", | |
"https://agents-mcp-hackathon-t2i.hf.space/gradio_api/mcp/sse", | |
"--transport", | |
"sse-only"], | |
) | |
# Model will be initialized dynamically based on user selection | |
# Load tools from all MCP servers using MCPClient | |
server_parameters = [kgb_server_parameters, T2I_server_parameters] | |
def initialize_model(model_provider, api_key_or_token): | |
"""Initialize the selected model with user credentials""" | |
if not api_key_or_token.strip(): | |
raise ValueError("Please provide your API key or token") | |
if model_provider == "Gemini (Google)": | |
return LiteLLMModel( | |
model_id="gemini/gemini-2.0-flash-exp", | |
api_key=api_key_or_token | |
) | |
elif model_provider == "Hugging Face (DeepSeek via Together)": | |
return InferenceClientModel( | |
model_id="deepseek-ai/DeepSeek-R1-0528", | |
provider="together", | |
token=api_key_or_token, | |
max_tokens=5000 | |
) | |
elif model_provider == "DeepSeek (Direct API)": | |
return OpenAIServerModel( | |
model_id="deepseek-chat", | |
api_key=api_key_or_token, | |
base_url="https://api.deepseek.com" | |
) | |
else: | |
raise ValueError(f"Unsupported model provider: {model_provider}") | |
def create_business_content_ui(): | |
"""Create specialized UI for business content creation""" | |
# Initialize MCP client and keep it alive for the entire UI session | |
print("π Initializing MCP client for the session...") | |
mcp = MCPClient(server_parameters) | |
with mcp: | |
# Load all MCP tools once and keep client alive | |
all_tools = mcp.get_tools() | |
print(f"β Loaded {len(all_tools)} MCP tools successfully") | |
def initialize_agents(model): | |
"""Initialize specialized agents using loaded MCP tools and user-selected model""" | |
# 1. Business Research Agent - Uses all MCP tools (Knowledge Graph Builder focus) | |
research_agent = CodeAgent( | |
tools=all_tools, | |
model=model, | |
add_base_tools=True, | |
name="business_researcher", | |
description="""Expert business researcher specializing in market analysis, competitive intelligence, and tech industry trends. | |
Uses knowledge graph tools to extract entities, relationships, and key business insights from topics. | |
Focuses on: market size, key players, business relationships, competitive landscape, and strategic context.""" | |
) | |
# 2. Content Strategy Agent - Creates structured business content | |
content_strategy_agent = ToolCallingAgent( | |
tools=[], | |
model=model, | |
max_steps=3, | |
name="content_strategist", | |
description="""Professional business writer specializing in executive-level content creation. | |
Creates structured, strategic business content including market analyses, competitive briefs, and strategic recommendations. | |
Writes for C-level executives, investors, and business stakeholders with focus on actionable insights.""" | |
) | |
# 3. Content Formatter Agent - Professional document formatting | |
content_formatter_agent = ToolCallingAgent( | |
tools=[], | |
model=model, | |
max_steps=2, | |
name="content_formatter", | |
description="""Document formatting specialist focused on professional business document structure. | |
Converts content into well-structured markdown with proper headers, tables, bullet points, and professional formatting. | |
Ensures consistency, readability, and professional presentation standards.""" | |
) | |
# 4. Visual Creation Agent - Uses all MCP tools (Text-to-Image focus) | |
visual_agent = CodeAgent( | |
tools=all_tools, | |
model=model, | |
add_base_tools=True, | |
name="visual_designer", | |
description="""Business visualization specialist creating professional infographics, charts, and presentation visuals. | |
Uses text-to-image tools to convert content into compelling visual formats suitable for executive presentations. | |
Focuses on clean, professional designs that enhance business storytelling.""" | |
) | |
# Business Content Manager - Coordinates all agents | |
business_content_manager = CodeAgent( | |
tools=all_tools, | |
model=model, | |
managed_agents=[research_agent, content_strategy_agent, content_formatter_agent, visual_agent], | |
additional_authorized_imports=["json", "re", "datetime"], | |
add_base_tools=True, | |
name="agentic_inkwell_manager", | |
description="""Agentic Inkwell Manager - Coordinates multi-agent business content creation workflow. | |
Manages the complete pipeline from research to final formatted output with optional visual conversion. | |
Where specialized agents gather around the digital inkwell to craft intelligence together.""" | |
) | |
return business_content_manager | |
# Content type options | |
content_types = [ | |
"Market Analysis Report", | |
"Competitive Intelligence Brief", | |
"Technology Trend Analysis", | |
"Product Launch Strategy", | |
"Investment Research Report", | |
"Strategic Planning Document" | |
] | |
# Writing style options | |
writing_styles = [ | |
"Executive Summary (C-level audience)", | |
"Technical Brief (Developer/Engineer audience)", | |
"Investor Pitch (VC/Stakeholder audience)", | |
"Market Research (Analyst audience)", | |
"Internal Memo (Team communication)" | |
] | |
# Visual style options | |
visual_styles = [ | |
"Professional Infographics", | |
"Corporate Presentation Style", | |
"Minimalist Charts", | |
"Executive Dashboard", | |
"Technical Diagrams", | |
"No Visuals (Text Only)" | |
] | |
with gr.Blocks(title="Agentic Inkwell", theme=gr.themes.Soft()) as demo: | |
gr.Markdown("# βοΈ Agentic Inkwell") | |
gr.Markdown("*Where Agents Craft Intelligence* - Generate comprehensive business reports with collaborative agentic writing") | |
# Model Configuration Section | |
with gr.Row(): | |
with gr.Column(): | |
gr.Markdown("### π€ Model Configuration") | |
model_provider = gr.Dropdown( | |
choices=[ | |
"Gemini (Google)", | |
"Hugging Face (DeepSeek via Together)", | |
"DeepSeek (Direct API)" | |
], | |
label="Select AI Model Provider", | |
value="Gemini (Google)", | |
info="Choose your preferred AI model provider" | |
) | |
api_key_input = gr.Textbox( | |
label="API Key / Token", | |
placeholder="Enter your API key or token here...", | |
type="password", | |
info="Your API key will be used securely and not stored" | |
) | |
gr.Markdown(""" | |
**π Where to get your API keys:** | |
- **Gemini**: Get free API key at [Google AI Studio](https://aistudio.google.com/app/apikey) | |
- **Hugging Face**: Get free token at [HF Settings](https://huggingface.co/settings/tokens) | |
- **DeepSeek**: Get API key at [DeepSeek Platform](https://platform.deepseek.com/api_keys) | |
""", elem_classes=["api-info"]) | |
with gr.Row(): | |
with gr.Column(scale=2): | |
# Main input | |
topic_input = gr.Textbox( | |
label="π Business Topic or Research Question", | |
placeholder="e.g., 'AI Agent frameworks market analysis 2025' or 'NVIDIA vs AMD in AI chip market'", | |
lines=3 | |
) | |
# Content controls | |
with gr.Row(): | |
content_type = gr.Dropdown( | |
choices=content_types, | |
label="π Content Type", | |
value="Market Analysis Report" | |
) | |
writing_style = gr.Dropdown( | |
choices=writing_styles, | |
label="βοΈ Writing Style", | |
value="Executive Summary (C-level audience)" | |
) | |
with gr.Row(): | |
visual_style = gr.Dropdown( | |
choices=visual_styles, | |
label="π¨ Visual Output", | |
value="No Visuals (Text Only)" | |
) | |
include_sources = gr.Checkbox( | |
label="π Include Source References", | |
value=True | |
) | |
# Generate button | |
generate_btn = gr.Button("βοΈ Craft with Agentic Inkwell", variant="primary", size="lg") | |
with gr.Column(scale=1): | |
# Status and progress | |
status_box = gr.Textbox( | |
label="π Generation Status", | |
value="Ready to generate content...", | |
interactive=False, | |
lines=8 | |
) | |
# Output section | |
with gr.Row(): | |
with gr.Column(): | |
# Main content output | |
content_output = gr.Textbox( | |
label="π Generated Business Content (Markdown)", | |
lines=20, | |
max_lines=30, | |
show_copy_button=True | |
) | |
# Action buttons row | |
with gr.Row(): | |
# Download button | |
download_btn = gr.DownloadButton( | |
label="πΎ Download Markdown", | |
visible=False | |
) | |
# Visual conversion button (appears after content generation) | |
convert_visual_btn = gr.Button( | |
"π¨ Convert to Images", | |
variant="secondary", | |
visible=False | |
) | |
# Visual output section (shown when visuals are generated) | |
with gr.Row(visible=False) as visual_output_row: | |
with gr.Column(): | |
visual_status = gr.Textbox( | |
label="π¨ Image Conversion Status", | |
interactive=False, | |
lines=3 | |
) | |
visual_output = gr.Gallery( | |
label="πΌοΈ Generated Images", | |
columns=2, | |
height=500, | |
show_label=True | |
) | |
def generate_business_content(topic, content_type, writing_style, visual_style, include_sources, model_provider, api_key): | |
"""Main function to coordinate business content generation""" | |
if not topic.strip(): | |
return "Please enter a business topic or research question.", "", None, gr.update(visible=False), gr.update(visible=False) | |
if not api_key.strip(): | |
return "Please provide your API key or token.", "", None, gr.update(visible=False), gr.update(visible=False) | |
try: | |
# Initialize the user-selected model | |
yield "π€ Initializing your selected AI model...", "", None, gr.update(visible=False), gr.update(visible=False) | |
try: | |
model = initialize_model(model_provider, api_key) | |
except Exception as e: | |
error_msg = f"β Failed to initialize {model_provider}: {str(e)}" | |
yield error_msg, "", None, gr.update(visible=False), gr.update(visible=False) | |
return | |
# Initialize agents with the user-selected model | |
yield "π§ Setting up specialized agents...", "", None, gr.update(visible=False), gr.update(visible=False) | |
manager = initialize_agents(model) | |
# Update status | |
status = "π Starting business research..." | |
yield status, "", None, gr.update(visible=False), gr.update(visible=False) | |
# Create detailed prompt for the manager | |
prompt = f""" | |
Create a comprehensive {content_type.lower()} about: {topic} | |
Requirements: | |
- Writing Style: {writing_style} | |
- Include source references: {include_sources} | |
- Visual conversion needed: {visual_style != 'No Visuals (Text Only)'} | |
- Visual style: {visual_style if visual_style != 'No Visuals (Text Only)' else 'None'} | |
Follow this workflow: | |
1. Use business_researcher to gather comprehensive market intelligence and competitive data | |
2. Use content_strategist to create structured business content with strategic insights | |
3. Use content_formatter to format into professional markdown document | |
4. {"Use visual_designer to create professional visuals if requested" if visual_style != 'No Visuals (Text Only)' else "Skip visual generation"} | |
Deliver a complete, professional business document ready for executive presentation. | |
""" | |
# Update status | |
status = "π€ Coordinating multi-agent content creation..." | |
yield status, "", None, gr.update(visible=False), gr.update(visible=False) | |
# Generate content using the manager | |
result = manager.run(prompt) | |
# Update status | |
status = "β Content generation completed successfully!" | |
# Prepare download file | |
import tempfile | |
import os | |
temp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False, encoding='utf-8') | |
temp_file.write(result) | |
temp_file.close() | |
# Show/hide visual gallery based on whether visuals were generated | |
show_visuals = visual_style != 'No Visuals (Text Only)' and "![" in result | |
yield ( | |
status, | |
result, | |
temp_file.name, | |
gr.update(visible=True), # download button | |
gr.update(visible=True) # convert to images button | |
) | |
except Exception as e: | |
error_msg = f"β Error generating content: {str(e)}" | |
yield error_msg, "", None, gr.update(visible=False), gr.update(visible=False) | |
def create_business_visuals(content_text, model_provider, api_key): | |
"""Convert text content to images using T2l_text_to_images_and_base64_generator tool""" | |
if not content_text.strip(): | |
return "β No content available to convert", [] | |
if not api_key.strip(): | |
return "β Please provide your API key or token", [] | |
try: | |
# Initialize model for visual conversion | |
yield "π€ Initializing model for image conversion...", [] | |
try: | |
model = initialize_model(model_provider, api_key) | |
except Exception as e: | |
yield f"β Failed to initialize model: {str(e)}", [] | |
return | |
# Use already loaded MCP tools | |
yield "π¨ Converting text to images...", [] | |
# Create visual agent with already loaded tools | |
visual_agent = CodeAgent( | |
tools=all_tools, | |
model=model, | |
add_base_tools=True, | |
name="t2i_visual_converter" | |
) | |
# Directly convert the content text to images | |
result = visual_agent.run(f""" | |
Use the T2l_text_to_images_and_base64_generator tool to convert this text to images: | |
text_content: "{content_text[:1000]}" | |
aspect_ratio_str: "16:9 (Widescreen)" | |
font_size: 36 | |
style: "plain" | |
bg_color_name: "White" | |
font_choice: "Arial" | |
Convert the business content to professional images. | |
""") | |
if result: | |
yield "β Successfully converted text to images!", [("Business Content", result)] | |
else: | |
yield "β οΈ No images were generated", [] | |
except Exception as e: | |
error_msg = f"β Image conversion failed: {str(e)}" | |
yield error_msg, [] | |
# Connect the generate button | |
generate_btn.click( | |
fn=generate_business_content, | |
inputs=[topic_input, content_type, writing_style, visual_style, include_sources, model_provider, api_key_input], | |
outputs=[status_box, content_output, download_btn, download_btn, convert_visual_btn], | |
show_progress=True | |
) | |
# Connect the convert to images button - directly convert text to images | |
convert_visual_btn.click( | |
fn=create_business_visuals, | |
inputs=[content_output, model_provider, api_key_input], | |
outputs=[visual_status, visual_output], | |
show_progress=True | |
).then( | |
fn=lambda: gr.update(visible=True), | |
outputs=visual_output_row | |
) | |
# Example buttons for quick testing | |
with gr.Row(): | |
gr.Markdown("### π― Quick Examples:") | |
example1_btn = gr.Button("π± AI Smartphone Market", size="sm") | |
example2_btn = gr.Button("π EV Battery Tech", size="sm") | |
example3_btn = gr.Button("βοΈ Cloud AI Services", size="sm") | |
def set_example1(): | |
return "AI-powered smartphone features market analysis 2025" | |
def set_example2(): | |
return "Electric vehicle battery technology competitive landscape" | |
def set_example3(): | |
return "Cloud-based AI services market opportunities and threats" | |
example1_btn.click(fn=set_example1, outputs=topic_input) | |
example2_btn.click(fn=set_example2, outputs=topic_input) | |
example3_btn.click(fn=set_example3, outputs=topic_input) | |
return demo | |
if __name__ == "__main__": | |
# Launch the business content creation interface | |
demo = create_business_content_ui() | |
demo.launch() |