|
|
"""
|
|
|
CogniHive Gradio Demo - HuggingFace Spaces
|
|
|
|
|
|
Interactive demo showcasing:
|
|
|
1. Agent Network Visualization
|
|
|
2. "Who Knows What" Queries
|
|
|
3. Live Query Routing
|
|
|
4. Memory Storage & Recall
|
|
|
"""
|
|
|
|
|
|
import os
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
|
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
|
src_path = os.path.join(current_dir, "src")
|
|
|
if os.path.exists(src_path):
|
|
|
sys.path.insert(0, src_path)
|
|
|
|
|
|
import gradio as gr
|
|
|
from typing import List, Tuple, Dict, Any
|
|
|
import json
|
|
|
|
|
|
|
|
|
from cognihive import Hive
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_demo_hive() -> Hive:
|
|
|
"""Create a pre-populated demo hive."""
|
|
|
hive = Hive(name="demo")
|
|
|
|
|
|
|
|
|
hive.register_agent(
|
|
|
"python_expert",
|
|
|
expertise=["python", "fastapi", "django", "testing", "async"],
|
|
|
role="Python Developer"
|
|
|
)
|
|
|
hive.register_agent(
|
|
|
"data_scientist",
|
|
|
expertise=["sql", "pandas", "machine-learning", "analytics", "statistics"],
|
|
|
role="Data Scientist"
|
|
|
)
|
|
|
hive.register_agent(
|
|
|
"frontend_dev",
|
|
|
expertise=["react", "typescript", "css", "javascript", "ui-ux"],
|
|
|
role="Frontend Developer"
|
|
|
)
|
|
|
hive.register_agent(
|
|
|
"devops_engineer",
|
|
|
expertise=["docker", "kubernetes", "aws", "ci-cd", "terraform"],
|
|
|
role="DevOps Engineer"
|
|
|
)
|
|
|
hive.register_agent(
|
|
|
"tech_writer",
|
|
|
expertise=["documentation", "api-docs", "tutorials", "examples"],
|
|
|
role="Technical Writer"
|
|
|
)
|
|
|
|
|
|
|
|
|
memories = [
|
|
|
("Use async/await with FastAPI for 10x better performance", "python_expert", ["python", "fastapi", "performance"]),
|
|
|
("pytest-asyncio is essential for testing async code", "python_expert", ["python", "testing", "async"]),
|
|
|
("Connection pooling with asyncpg gives 3x throughput", "data_scientist", ["sql", "performance", "postgres"]),
|
|
|
("Use EXPLAIN ANALYZE to debug slow queries", "data_scientist", ["sql", "debugging", "optimization"]),
|
|
|
("React 19 Server Components reduce bundle by 40%", "frontend_dev", ["react", "performance", "server-components"]),
|
|
|
("CSS container queries > media queries for components", "frontend_dev", ["css", "responsive", "modern"]),
|
|
|
("Use multi-stage Docker builds for smaller images", "devops_engineer", ["docker", "optimization", "best-practices"]),
|
|
|
("Terraform state should be stored in S3 with locking", "devops_engineer", ["terraform", "aws", "infrastructure"]),
|
|
|
("Always include code examples in API documentation", "tech_writer", ["documentation", "api-docs", "best-practices"]),
|
|
|
("Use OpenAPI specs to auto-generate client libraries", "tech_writer", ["api-docs", "openapi", "automation"]),
|
|
|
]
|
|
|
|
|
|
for content, agent, topics in memories:
|
|
|
hive.remember(content, agent=agent, topics=topics)
|
|
|
|
|
|
return hive
|
|
|
|
|
|
|
|
|
|
|
|
HIVE = create_demo_hive()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_agents_display() -> str:
|
|
|
"""Get formatted display of all agents and their expertise."""
|
|
|
lines = ["## Registered Agents\n"]
|
|
|
|
|
|
matrix = HIVE.expertise_matrix()
|
|
|
for agent_name, domains in matrix.items():
|
|
|
agent = HIVE.get_agent(agent_name)
|
|
|
role = agent.role if agent else ""
|
|
|
|
|
|
top_domains = sorted(domains.items(), key=lambda x: x[1], reverse=True)[:5]
|
|
|
domain_badges = " ".join([f"`{d}`" for d, _ in top_domains if _ > 0.3])
|
|
|
|
|
|
lines.append(f"### {agent_name}")
|
|
|
lines.append(f"**Role:** {role}")
|
|
|
lines.append(f"**Expertise:** {domain_badges}")
|
|
|
lines.append("")
|
|
|
|
|
|
return "\n".join(lines)
|
|
|
|
|
|
|
|
|
def who_knows_query(topic: str) -> Tuple[str, str]:
|
|
|
"""Query who knows about a topic."""
|
|
|
if not topic.strip():
|
|
|
return "Please enter a topic to search.", ""
|
|
|
|
|
|
experts = HIVE.who_knows(topic)
|
|
|
|
|
|
if not experts:
|
|
|
return f"No experts found for: **{topic}**", ""
|
|
|
|
|
|
|
|
|
lines = [f"## Experts on '{topic}'\n"]
|
|
|
|
|
|
chart_data = []
|
|
|
for name, score in experts:
|
|
|
agent = HIVE.get_agent(name)
|
|
|
role = agent.role if agent else ""
|
|
|
|
|
|
|
|
|
bar_width = int(score * 20)
|
|
|
bar = "█" * bar_width + "░" * (20 - bar_width)
|
|
|
|
|
|
lines.append(f"**{name}** ({role})")
|
|
|
lines.append(f"`[{bar}]` {score:.2f}")
|
|
|
lines.append("")
|
|
|
|
|
|
chart_data.append({"agent": name, "score": score})
|
|
|
|
|
|
return "\n".join(lines), json.dumps(chart_data, indent=2)
|
|
|
|
|
|
|
|
|
def ask_query(question: str) -> Tuple[str, str, str]:
|
|
|
"""Ask a question and get routed to an expert."""
|
|
|
if not question.strip():
|
|
|
return "Please enter a question.", "", ""
|
|
|
|
|
|
result = HIVE.ask(question)
|
|
|
|
|
|
|
|
|
routing_lines = ["## Routing Decision\n"]
|
|
|
routing_lines.append(f"**Question:** {question}")
|
|
|
routing_lines.append("")
|
|
|
routing_lines.append(f"**Routed to:** {result['expert'] or 'No expert found'}")
|
|
|
routing_lines.append(f"**Confidence:** {result['confidence']:.2f}")
|
|
|
|
|
|
if result['secondary_experts']:
|
|
|
routing_lines.append(f"**Secondary experts:** {', '.join(result['secondary_experts'])}")
|
|
|
|
|
|
routing_lines.append("")
|
|
|
routing_lines.append("### Reasoning")
|
|
|
routing_lines.append(result['reasoning'] or "No specific reasoning available.")
|
|
|
|
|
|
|
|
|
memory_lines = ["## Relevant Memories\n"]
|
|
|
if result['memories']:
|
|
|
for i, (mem, score) in enumerate(zip(result['memories'], result['scores']), 1):
|
|
|
memory_lines.append(f"**{i}. From {mem.owner_name}** (relevance: {score:.2f})")
|
|
|
memory_lines.append(f"> {mem.content}")
|
|
|
memory_lines.append("")
|
|
|
else:
|
|
|
memory_lines.append("No relevant memories found.")
|
|
|
|
|
|
return "\n".join(routing_lines), "\n".join(memory_lines), result['expert']
|
|
|
|
|
|
|
|
|
def add_memory(content: str, agent: str, topics: str) -> str:
|
|
|
"""Add a new memory to the hive."""
|
|
|
if not content.strip():
|
|
|
return "Please enter memory content."
|
|
|
|
|
|
if not agent.strip():
|
|
|
return "Please select an agent."
|
|
|
|
|
|
topic_list = [t.strip() for t in topics.split(",") if t.strip()]
|
|
|
|
|
|
try:
|
|
|
memory = HIVE.remember(content, agent=agent, topics=topic_list)
|
|
|
return f"Memory stored successfully!\n\n**ID:** `{memory.id[:8]}...`\n**Agent:** {agent}\n**Topics:** {', '.join(topic_list) or 'None'}"
|
|
|
except Exception as e:
|
|
|
return f"Error storing memory: {str(e)}"
|
|
|
|
|
|
|
|
|
def recall_memories(query: str) -> str:
|
|
|
"""Search for memories."""
|
|
|
if not query.strip():
|
|
|
return "Please enter a search query."
|
|
|
|
|
|
results = HIVE.recall(query, top_k=5)
|
|
|
|
|
|
if not results:
|
|
|
return f"No memories found for: **{query}**"
|
|
|
|
|
|
lines = [f"## Memories matching '{query}'\n"]
|
|
|
|
|
|
for i, (memory, score) in enumerate(results, 1):
|
|
|
lines.append(f"### {i}. {memory.owner_name} (score: {score:.2f})")
|
|
|
lines.append(f"> {memory.content}")
|
|
|
if memory.topics:
|
|
|
lines.append(f"**Topics:** {', '.join(memory.topics)}")
|
|
|
lines.append("")
|
|
|
|
|
|
return "\n".join(lines)
|
|
|
|
|
|
|
|
|
def get_hive_stats() -> str:
|
|
|
"""Get hive statistics."""
|
|
|
stats = HIVE.stats()
|
|
|
|
|
|
lines = [
|
|
|
"## Hive Statistics\n",
|
|
|
f"**Name:** {stats['name']}",
|
|
|
f"**Agents:** {stats['agent_count']}",
|
|
|
f"**Memories:** {stats['memory_count']}",
|
|
|
f"**Queries Processed:** {stats['metrics']['queries_processed']}",
|
|
|
f"**Routing Decisions:** {stats['metrics']['routing_decisions']}",
|
|
|
]
|
|
|
|
|
|
return "\n".join(lines)
|
|
|
|
|
|
|
|
|
def reset_hive() -> str:
|
|
|
"""Reset the hive to initial state."""
|
|
|
global HIVE
|
|
|
HIVE = create_demo_hive()
|
|
|
return "Hive reset to initial state with demo data."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_demo():
|
|
|
"""Create the Gradio demo interface."""
|
|
|
|
|
|
with gr.Blocks(
|
|
|
title="CogniHive - Transactive Memory for AI Agents",
|
|
|
theme=gr.themes.Soft(
|
|
|
primary_hue="amber",
|
|
|
secondary_hue="orange",
|
|
|
),
|
|
|
css="""
|
|
|
.gradio-container { max-width: 1200px !important; }
|
|
|
.main-header { text-align: center; margin-bottom: 20px; }
|
|
|
.feature-box { border: 1px solid #e0e0e0; border-radius: 8px; padding: 15px; margin: 10px 0; }
|
|
|
"""
|
|
|
) as demo:
|
|
|
|
|
|
|
|
|
gr.Markdown("""
|
|
|
# CogniHive
|
|
|
### The World's First Transactive Memory System for Multi-Agent AI
|
|
|
|
|
|
**"Mem0 gives one agent a brain. CogniHive gives your agent team a collective mind."**
|
|
|
|
|
|
---
|
|
|
""")
|
|
|
|
|
|
with gr.Tabs():
|
|
|
|
|
|
|
|
|
with gr.TabItem("Who Knows What"):
|
|
|
gr.Markdown("""
|
|
|
## Find Experts on Any Topic
|
|
|
|
|
|
This is the core innovation of CogniHive: **Transactive Memory**.
|
|
|
Ask "who knows about X" and find the right expert instantly.
|
|
|
""")
|
|
|
|
|
|
with gr.Row():
|
|
|
with gr.Column(scale=1):
|
|
|
topic_input = gr.Textbox(
|
|
|
label="Topic to search",
|
|
|
placeholder="e.g., python optimization, database security, react components",
|
|
|
lines=1
|
|
|
)
|
|
|
who_knows_btn = gr.Button("Find Experts", variant="primary")
|
|
|
|
|
|
gr.Examples(
|
|
|
examples=[
|
|
|
["python async programming"],
|
|
|
["database optimization"],
|
|
|
["react performance"],
|
|
|
["docker best practices"],
|
|
|
["API documentation"],
|
|
|
],
|
|
|
inputs=topic_input,
|
|
|
label="Try these topics:"
|
|
|
)
|
|
|
|
|
|
with gr.Column(scale=2):
|
|
|
who_knows_output = gr.Markdown(label="Expert Results")
|
|
|
who_knows_data = gr.Code(label="Raw Data (JSON)", language="json", visible=False)
|
|
|
|
|
|
who_knows_btn.click(
|
|
|
who_knows_query,
|
|
|
inputs=[topic_input],
|
|
|
outputs=[who_knows_output, who_knows_data]
|
|
|
)
|
|
|
|
|
|
|
|
|
with gr.TabItem("Ask & Route"):
|
|
|
gr.Markdown("""
|
|
|
## Automatic Query Routing
|
|
|
|
|
|
Ask any question and CogniHive will automatically route it to the best expert
|
|
|
and retrieve relevant memories.
|
|
|
""")
|
|
|
|
|
|
with gr.Row():
|
|
|
with gr.Column(scale=1):
|
|
|
question_input = gr.Textbox(
|
|
|
label="Your Question",
|
|
|
placeholder="e.g., How do I improve my Python code performance?",
|
|
|
lines=2
|
|
|
)
|
|
|
ask_btn = gr.Button("Ask the Hive", variant="primary")
|
|
|
|
|
|
routed_to = gr.Textbox(label="Routed to Expert", interactive=False)
|
|
|
|
|
|
gr.Examples(
|
|
|
examples=[
|
|
|
["How do I write better async Python code?"],
|
|
|
["What's the best way to optimize SQL queries?"],
|
|
|
["How should I structure my React components?"],
|
|
|
["What are Docker best practices?"],
|
|
|
["How do I document my API effectively?"],
|
|
|
],
|
|
|
inputs=question_input,
|
|
|
label="Try these questions:"
|
|
|
)
|
|
|
|
|
|
with gr.Column(scale=2):
|
|
|
routing_output = gr.Markdown(label="Routing Decision")
|
|
|
memories_output = gr.Markdown(label="Relevant Memories")
|
|
|
|
|
|
ask_btn.click(
|
|
|
ask_query,
|
|
|
inputs=[question_input],
|
|
|
outputs=[routing_output, memories_output, routed_to]
|
|
|
)
|
|
|
|
|
|
|
|
|
with gr.TabItem("Memory"):
|
|
|
gr.Markdown("""
|
|
|
## Store & Recall Team Knowledge
|
|
|
|
|
|
Add new memories to the hive or search existing knowledge.
|
|
|
""")
|
|
|
|
|
|
with gr.Row():
|
|
|
|
|
|
with gr.Column():
|
|
|
gr.Markdown("### Add New Memory")
|
|
|
memory_content = gr.Textbox(
|
|
|
label="Memory Content",
|
|
|
placeholder="Enter knowledge to store...",
|
|
|
lines=3
|
|
|
)
|
|
|
memory_agent = gr.Dropdown(
|
|
|
label="Agent",
|
|
|
choices=["python_expert", "data_scientist", "frontend_dev", "devops_engineer", "tech_writer"],
|
|
|
value="python_expert"
|
|
|
)
|
|
|
memory_topics = gr.Textbox(
|
|
|
label="Topics (comma-separated)",
|
|
|
placeholder="e.g., python, performance, tips"
|
|
|
)
|
|
|
add_memory_btn = gr.Button("Store Memory", variant="primary")
|
|
|
add_result = gr.Markdown()
|
|
|
|
|
|
|
|
|
with gr.Column():
|
|
|
gr.Markdown("### Search Memories")
|
|
|
search_query = gr.Textbox(
|
|
|
label="Search Query",
|
|
|
placeholder="Search for relevant memories...",
|
|
|
lines=1
|
|
|
)
|
|
|
search_btn = gr.Button("Search", variant="secondary")
|
|
|
search_results = gr.Markdown()
|
|
|
|
|
|
add_memory_btn.click(
|
|
|
add_memory,
|
|
|
inputs=[memory_content, memory_agent, memory_topics],
|
|
|
outputs=[add_result]
|
|
|
)
|
|
|
|
|
|
search_btn.click(
|
|
|
recall_memories,
|
|
|
inputs=[search_query],
|
|
|
outputs=[search_results]
|
|
|
)
|
|
|
|
|
|
|
|
|
with gr.TabItem("Agents"):
|
|
|
gr.Markdown("""
|
|
|
## Agent Network & Expertise
|
|
|
|
|
|
View all registered agents and their areas of expertise.
|
|
|
""")
|
|
|
|
|
|
with gr.Row():
|
|
|
with gr.Column():
|
|
|
refresh_btn = gr.Button("Refresh Agent List")
|
|
|
agents_display = gr.Markdown(value=get_agents_display())
|
|
|
|
|
|
with gr.Column():
|
|
|
stats_display = gr.Markdown(value=get_hive_stats(), label="Hive Stats")
|
|
|
reset_btn = gr.Button("Reset Hive", variant="secondary")
|
|
|
reset_result = gr.Markdown()
|
|
|
|
|
|
refresh_btn.click(get_agents_display, outputs=[agents_display])
|
|
|
refresh_btn.click(get_hive_stats, outputs=[stats_display])
|
|
|
reset_btn.click(reset_hive, outputs=[reset_result])
|
|
|
|
|
|
|
|
|
gr.Markdown("""
|
|
|
---
|
|
|
|
|
|
### About CogniHive
|
|
|
|
|
|
CogniHive implements **Transactive Memory Systems (TMS)** for AI agents -
|
|
|
a concept from cognitive science that enables teams to know "who knows what."
|
|
|
|
|
|
**Key Features:**
|
|
|
- "Who Knows What" queries
|
|
|
- Automatic expert routing
|
|
|
- Memory with access control
|
|
|
- Framework integrations (CrewAI, AutoGen, LangGraph)
|
|
|
|
|
|
[GitHub](https://github.com/vrush/cognihive) | [PyPI](https://pypi.org/project/cognihive/)
|
|
|
|
|
|
---
|
|
|
*Built with Gradio | Powered by ChromaDB*
|
|
|
""")
|
|
|
|
|
|
return demo
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
demo = create_demo()
|
|
|
demo.launch(
|
|
|
share=False,
|
|
|
server_name="0.0.0.0",
|
|
|
server_port=7860
|
|
|
)
|
|
|
|