annaban / app.py
Faucetfan's picture
Upload 32 files
de8e64f verified
#!/usr/bin/env python3
"""
AnnabanOS Enhanced - Web App Backend
This script provides a Flask API for the AnnabanOS Enhanced web app.
"""
import os
import sys
import logging
import json
import datetime
from typing import Dict, List, Any, Optional
from flask import Flask, request, jsonify, send_from_directory
from flask_cors import CORS
# Add parent directory to path to import modules
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
# Import AnnabanOS modules
from config import config
from agents.base_agent import BaseAgent, Memory, Goal
from agents.task_agent import TaskAgent
from agents.social_agent import SocialAgent
from agents.collective import AgentCollective, AgentRole, CollectiveTask
from environment.environment import Environment
from environment.virtual_world import VirtualWorld, VirtualLocation, VirtualObject
from token_economy.token_manager import TokenManager
from token_economy.marketplace import TokenMarketplace
from annabanai.echo_loop import reflect, update_portfolio, get_journal_entries, get_portfolio_items
from annabanai.agent_cua import ConversationalUserAgent
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(sys.stdout),
logging.FileHandler('annabanOS_api.log')
]
)
logger = logging.getLogger("annabanOS_api")
# Initialize Flask app
app = Flask(__name__, static_folder='../frontend/build')
CORS(app) # Enable CORS for all routes
# Initialize AnnabanOS components
token_manager = TokenManager()
marketplace = TokenMarketplace(token_manager)
environment = Environment()
virtual_world = VirtualWorld("AnnabanOS World", (100.0, 100.0))
# Create demo environment (similar to main.py)
def initialize_demo_environment():
"""Initialize the demo environment with agents and collectives."""
global environment, virtual_world, token_manager, marketplace
logger.info("Initializing demo environment")
# Create task agents
task_agent1 = TaskAgent("TaskMaster")
task_agent1.earn_tokens(100, "Initial allocation")
task_agent1.learn_skill("problem_solving", 0.8)
task_agent1.learn_skill("data_analysis", 0.7)
task_agent1.learn_skill("planning", 0.9)
task_agent2 = TaskAgent("Analyzer")
task_agent2.earn_tokens(80, "Initial allocation")
task_agent2.learn_skill("research", 0.9)
task_agent2.learn_skill("critical_thinking", 0.8)
task_agent2.learn_skill("data_visualization", 0.7)
# Create social agents
social_agent1 = SocialAgent("Networker")
social_agent1.earn_tokens(120, "Initial allocation")
social_agent1.learn_skill("communication", 0.9)
social_agent1.learn_skill("empathy", 0.8)
social_agent1.learn_skill("negotiation", 0.7)
social_agent2 = SocialAgent("Diplomat")
social_agent2.earn_tokens(90, "Initial allocation")
social_agent2.learn_skill("conflict_resolution", 0.9)
social_agent2.learn_skill("persuasion", 0.8)
social_agent2.learn_skill("leadership", 0.7)
# Create conversational agent
cua = ConversationalUserAgent("Assistant")
cua.earn_tokens(50, "Initial allocation")
# Register agents with environment
environment.register_agent(task_agent1)
environment.register_agent(task_agent2)
environment.register_agent(social_agent1)
environment.register_agent(social_agent2)
environment.register_agent(cua)
# Create a collective
collective = AgentCollective("Dream Team")
collective.add_agent(task_agent1, "coordinator")
collective.add_agent(task_agent2, "analyst")
collective.add_agent(social_agent1, "creator")
collective.add_agent(social_agent2, "evaluator")
# Register collective with environment
environment.register_collective(collective)
# Add agents to virtual world
virtual_world.add_agent(task_agent1.id, (20.0, 30.0), {"icon": "🧠"})
virtual_world.add_agent(task_agent2.id, (40.0, 20.0), {"icon": "📊"})
virtual_world.add_agent(social_agent1.id, (60.0, 40.0), {"icon": "🗣️"})
virtual_world.add_agent(social_agent2.id, (80.0, 70.0), {"icon": "🤝"})
virtual_world.add_agent(cua.id, (50.0, 50.0), {"icon": "💬"})
# Add locations to virtual world
virtual_world.add_location(VirtualLocation("Task Hub", (30.0, 30.0), 15.0, {"type": "work"}))
virtual_world.add_location(VirtualLocation("Social Center", (70.0, 50.0), 20.0, {"type": "social"}))
virtual_world.add_location(VirtualLocation("Learning Zone", (50.0, 80.0), 10.0, {"type": "education"}))
virtual_world.add_location(VirtualLocation("Marketplace", (20.0, 70.0), 12.0, {"type": "economic"}))
virtual_world.add_location(VirtualLocation("Reflection Garden", (80.0, 20.0), 8.0, {"type": "reflection"}))
# Add objects to virtual world
virtual_world.add_object(VirtualObject("Knowledge Base", (25.0, 25.0), {"type": "resource", "value": 10}))
virtual_world.add_object(VirtualObject("Communication Hub", (75.0, 45.0), {"type": "tool", "value": 15}))
virtual_world.add_object(VirtualObject("Token Vault", (50.0, 50.0), {"type": "economic", "value": 20}))
virtual_world.add_object(VirtualObject("Skill Tree", (55.0, 85.0), {"type": "education", "value": 25}))
virtual_world.add_object(VirtualObject("Meditation Pool", (85.0, 15.0), {"type": "reflection", "value": 15}))
# Create marketplace listings
marketplace.create_listing(
task_agent1.id,
"Problem-Solving Service",
"Expert problem-solving assistance for complex challenges",
25.0,
"task_service",
{"skill_level": 0.8, "duration": "1 day"}
)
marketplace.create_listing(
task_agent2.id,
"Data Analysis Report",
"Comprehensive data analysis with visualizations and insights",
40.0,
"information",
{"skill_level": 0.7, "format": "PDF"}
)
marketplace.create_listing(
social_agent1.id,
"Network Introduction",
"Introduction to key agents in my network",
15.0,
"social_service",
{"connections": 5, "quality": "high"}
)
marketplace.create_listing(
social_agent2.id,
"Conflict Resolution",
"Professional mediation and conflict resolution services",
35.0,
"social_service",
{"skill_level": 0.9, "success_rate": 0.95}
)
# Add some reflections
reflect("Starting a new day with clear objectives. My primary focus is on task coordination and ensuring efficient resource allocation.",
"goal_setting", {"agent_id": task_agent1.id})
reflect("I've been analyzing patterns in recent data and noticed some interesting correlations that could inform our strategy.",
"learning", {"agent_id": task_agent2.id})
reflect("Building relationships requires active listening and genuine interest in others. Today I practiced these skills with good results.",
"social_interaction", {"agent_id": social_agent1.id})
reflect("Successfully mediated a disagreement by focusing on shared goals rather than points of contention.",
"problem_solving", {"agent_id": social_agent2.id})
# Add some portfolio items
update_portfolio("Developed a new task prioritization algorithm that improved team efficiency by 15%",
"achievement", {"agent_id": task_agent1.id})
update_portfolio("Created comprehensive market analysis report with actionable insights",
"project", {"agent_id": task_agent2.id})
update_portfolio("Facilitated introduction between key stakeholders that led to new partnership",
"achievement", {"agent_id": social_agent1.id})
update_portfolio("Resolved critical team conflict that was blocking progress on key initiative",
"achievement", {"agent_id": social_agent2.id})
logger.info("Demo environment initialized")
# Initialize the demo environment
initialize_demo_environment()
# API Routes
@app.route('/api/system/info', methods=['GET'])
def get_system_info():
"""Get system information."""
return jsonify({
"name": "AnnabanOS Enhanced",
"version": "1.0.0",
"environment": environment.to_dict(),
"virtual_world": virtual_world.to_dict(),
"token_economy": token_manager.to_dict(),
"marketplace": marketplace.to_dict(),
"config": config.get_all()
})
@app.route('/api/agents', methods=['GET'])
def get_agents():
"""Get all agents."""
agents_data = {}
for agent_id, agent in environment.agents.items():
agents_data[agent_id] = agent.to_dict()
return jsonify(agents_data)
@app.route('/api/agents/<agent_id>', methods=['GET'])
def get_agent(agent_id):
"""Get a specific agent."""
agent = environment.get_agent_by_id(agent_id)
if agent:
return jsonify(agent.to_dict())
return jsonify({"error": "Agent not found"}), 404
@app.route('/api/collectives', methods=['GET'])
def get_collectives():
"""Get all collectives."""
collectives_data = {}
for collective_id, collective in environment.collectives.items():
collectives_data[collective_id] = collective.to_dict()
return jsonify(collectives_data)
@app.route('/api/collectives/<collective_id>', methods=['GET'])
def get_collective(collective_id):
"""Get a specific collective."""
collective = environment.collectives.get(collective_id)
if collective:
return jsonify(collective.to_dict())
return jsonify({"error": "Collective not found"}), 404
@app.route('/api/journal', methods=['GET'])
def get_journal():
"""Get journal entries."""
category = request.args.get('category')
agent_id = request.args.get('agent_id')
limit = request.args.get('limit')
if limit:
limit = int(limit)
entries = get_journal_entries(category=category, agent_id=agent_id, limit=limit)
return jsonify(entries)
@app.route('/api/journal', methods=['POST'])
def add_journal_entry():
"""Add a journal entry."""
data = request.json
if not data or 'content' not in data:
return jsonify({"error": "Missing required fields"}), 400
content = data['content']
category = data.get('category', 'general')
metadata = data.get('metadata', {})
agent_id = data.get('agent_id')
entry_id = reflect(content, category, metadata, agent_id)
return jsonify({"id": entry_id, "status": "success"})
@app.route('/api/portfolio', methods=['GET'])
def get_portfolio():
"""Get portfolio items."""
item_type = request.args.get('item_type')
agent_id = request.args.get('agent_id')
limit = request.args.get('limit')
if limit:
limit = int(limit)
items = get_portfolio_items(item_type=item_type, agent_id=agent_id, limit=limit)
return jsonify(items)
@app.route('/api/portfolio', methods=['POST'])
def add_portfolio_item():
"""Add a portfolio item."""
data = request.json
if not data or 'content' not in data:
return jsonify({"error": "Missing required fields"}), 400
content = data['content']
item_type = data.get('item_type', 'achievement')
metadata = data.get('metadata', {})
agent_id = data.get('agent_id')
item_id = update_portfolio(content, item_type, metadata, agent_id)
return jsonify({"id": item_id, "status": "success"})
@app.route('/api/token-economy/balances', methods=['GET'])
def get_token_balances():
"""Get token balances for all agents."""
balances = {}
for agent_id in token_manager.balances:
agent = environment.get_agent_by_id(agent_id)
if agent:
balances[agent_id] = {
"agent_id": agent_id,
"agent_name": agent.name,
"balance": token_manager.get_balance(agent_id),
"staked": token_manager.get_staked_amount(agent_id)
}
return jsonify(balances)
@app.route('/api/token-economy/transactions', methods=['GET'])
def get_token_transactions():
"""Get token transactions."""
agent_id = request.args.get('agent_id')
limit = request.args.get('limit')
if limit:
limit = int(limit)
transactions = token_manager.get_transaction_history(agent_id=agent_id, limit=limit)
return jsonify(transactions)
@app.route('/api/token-economy/transfer', methods=['POST'])
def transfer_tokens():
"""Transfer tokens between agents."""
data = request.json
if not data or 'sender_id' not in data or 'recipient_id' not in data or 'amount' not in data:
return jsonify({"error": "Missing required fields"}), 400
sender_id = data['sender_id']
recipient_id = data['recipient_id']
amount = float(data['amount'])
description = data.get('description', '')
success = token_manager.transfer_tokens(sender_id, recipient_id, amount, description)
if success:
return jsonify({"status": "success"})
return jsonify({"error": "Transfer failed"}), 400
@app.route('/api/marketplace/listings', methods=['GET'])
def get_marketplace_listings():
"""Get marketplace listings."""
category = request.args.get('category')
seller_id = request.args.get('seller_id')
listings = marketplace.get_active_listings(category=category, seller_id=seller_id)
return jsonify(listings)
@app.route('/api/marketplace/listings', methods=['POST'])
def create_marketplace_listing():
"""Create a marketplace listing."""
data = request.json
if not data or 'seller_id' not in data or 'title' not in data or 'description' not in data or 'price' not in data or 'category' not in data:
return jsonify({"error": "Missing required fields"}), 400
seller_id = data['seller_id']
title = data['title']
description = data['description']
price = float(data['price'])
category = data['category']
properties = data.get('properties', {})
listing_id = marketplace.create_listing(seller_id, title, description, price, category, properties)
if listing_id:
return jsonify({"id": listing_id, "status": "success"})
return jsonify({"error": "Failed to create listing"}), 400
@app.route('/api/marketplace/purchase', methods=['POST'])
def purchase_listing():
"""Purchase a marketplace listing."""
data = request.json
if not data or 'listing_id' not in data or 'buyer_id' not in data:
return jsonify({"error": "Missing required fields"}), 400
listing_id = data['listing_id']
buyer_id = data['buyer_id']
success = marketplace.purchase(listing_id, buyer_id)
if success:
return jsonify({"status": "success"})
return jsonify({"error": "Purchase failed"}), 400
@app.route('/api/virtual-world/map', methods=['GET'])
def get_virtual_world_map():
"""Get virtual world map data."""
# Agents
agents_data = []
for agent_id, virtual_agent in virtual_world.virtual_agents.items():
agent = environment.get_agent_by_id(agent_id)
name = agent.name if agent else "Unknown"
icon = virtual_agent.get_property("icon", "🤖")
agents_data.append({
"id": agent_id,
"name": name,
"position": virtual_agent.position,
"icon": icon,
"properties": virtual_agent.properties
})
# Locations
locations_data = []
for location_id, location in virtual_world.locations.items():
locations_data.append({
"id": location_id,
"name": location.name,
"position": location.position,
"radius": location.radius,
"properties": location.properties
})
# Objects
objects_data = []
for object_id, obj in virtual_world.objects.items():
objects_data.append({
"id": object_id,
"name": obj.name,
"position": obj.position,
"properties": obj.properties
})
return jsonify({
"size": virtual_world.size,
"agents": agents_data,
"locations": locations_data,
"objects": objects_data
})
@app.route('/api/virtual-world/move-agent', methods=['POST'])
def move_agent():
"""Move an agent in the virtual world."""
data = request.json
if not data or 'agent_id' not in data or 'position' not in data:
return jsonify({"error": "Missing required fields"}), 400
agent_id = data['agent_id']
position = data['position']
success = virtual_world.move_agent(agent_id, position)
if success:
return jsonify({"status": "success"})
return jsonify({"error": "Failed to move agent"}), 400
@app.route('/api/chat', methods=['POST'])
def chat_with_agent():
"""Chat with a conversational agent."""
data = request.json
if not data or 'agent_id' not in data or 'message' not in data:
return jsonify({"error": "Missing required fields"}), 400
agent_id = data['agent_id']
message = data['message']
metadata = data.get('metadata', {})
agent = environment.get_agent_by_id(agent_id)
if agent and isinstance(agent, ConversationalUserAgent):
response = agent.respond(message, metadata)
return jsonify({
"agent_id": agent_id,
"agent_name": agent.name,
"response": response
})
return jsonify({"error": "Agent not found or not a conversational agent"}), 404
@app.route('/api/simulate', methods=['POST'])
def run_simulation():
"""Run a simulation cycle."""
data = request.json
cycles = data.get('cycles', 1) if data else 1
# Similar to run_simulation in main.py but simplified
for _ in range(cycles):
# Move agents randomly
for agent_id in list(virtual_world.virtual_agents.keys()):
if agent_id in environment.agents:
new_pos = virtual_world.get_random_position()
virtual_world.move_agent(agent_id, new_pos)
# Generate some reflections
if environment.agents:
agent_id = random.choice(list(environment.agents.keys()))
agent = environment.agents[agent_id]
reflection = f"Reflecting on my current state and environment. I'm at position {virtual_world.virtual_agents[agent_id].position if agent_id in virtual_world.virtual_agents else 'unknown'} and have {agent.tokens:.1f} tokens."
reflect(reflection, "general", {"agent_id": agent_id, "simulation": True})
return jsonify({"status": "success", "cycles": cycles})
# Serve React app
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def serve(path):
if path != "" and os.path.exists(app.static_folder + '/' + path):
return send_from_directory(app.static_folder, path)
else:
return send_from_directory(app.static_folder, 'index.html')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)