Trae Assistant
Initial commit of Ocean Guard Agent with enhanced features
769efdb
import os
import json
import sqlite3
import random
import time
import requests
import traceback
from datetime import datetime, timedelta
from werkzeug.utils import secure_filename
from flask import Flask, render_template, jsonify, request, g, send_from_directory
app = Flask(__name__)
app.config['SECRET_KEY'] = 'ocean-guard-secret'
app.config['DATABASE'] = os.path.join(app.instance_path, 'ocean.db')
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB limit
app.config['UPLOAD_FOLDER'] = os.path.join(app.instance_path, 'uploads')
# Ensure directories exist
try:
os.makedirs(app.instance_path)
os.makedirs(app.config['UPLOAD_FOLDER'])
except OSError:
pass
# SiliconFlow Config
SILICON_KEY = "sk-vimuseiptfbomzegyuvmebjzooncsqbyjtlddrfodzcdskgi"
SILICON_URL = "https://api.siliconflow.cn/v1/chat/completions"
SILICON_MODEL = "Qwen/Qwen2.5-7B-Instruct"
# --- Database ---
def get_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = sqlite3.connect(app.config['DATABASE'])
db.row_factory = sqlite3.Row
return db
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.close()
def init_db():
with app.app_context():
db = get_db()
db.execute('''
CREATE TABLE IF NOT EXISTS assets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
type TEXT NOT NULL,
value REAL NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
db.execute('''
CREATE TABLE IF NOT EXISTS logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
event TEXT NOT NULL,
action TEXT NOT NULL,
result TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
db.commit()
# --- Error Handlers ---
@app.errorhandler(404)
def not_found_error(error):
return jsonify({"error": "Resource not found", "code": 404}), 404
@app.errorhandler(500)
def internal_error(error):
traceback.print_exc()
return jsonify({"error": "Internal server error", "code": 500}), 500
@app.errorhandler(413)
def request_entity_too_large(error):
return jsonify({"error": "File too large (Max 16MB)", "code": 413}), 413
# --- Mock Data Helpers ---
POSSIBLE_ENTITIES = [
{"type": "Great Pacific Garbage Patch Fragment", "severity": "Medium", "location": "Sector 7"},
{"type": "Deepwater Horizon Remnant Oil", "severity": "Critical", "location": "Sector 3"},
{"type": "Humpback Whale Pod (Migration)", "severity": "None", "location": "Sector 9"},
{"type": "Illegal IUU Fishing Trawler", "severity": "High", "location": "Sector 2"},
{"type": "Abandoned Ghost Net (2 tons)", "severity": "High", "location": "Sector 5"},
{"type": "Coral Reef Bleaching Event", "severity": "Medium", "location": "Sector 1"},
{"type": "Rare Leatherback Turtle", "severity": "None", "location": "Sector 4"},
{"type": "Underwater Volcanic Activity", "severity": "Low", "location": "Sector 8"}
]
# --- Routes ---
@app.route('/')
def index():
return render_template('index.html')
@app.route('/api/scan', methods=['GET'])
def scan_ocean():
# Simulate scanning logic
entity = random.choice(POSSIBLE_ENTITIES)
# Add random coordinates for map
entity['lat'] = 30.0 + random.uniform(-0.5, 0.5)
entity['lng'] = 122.0 + random.uniform(-0.5, 0.5)
entity['depth'] = random.randint(10, 800)
entity['signal_strength'] = random.randint(40, 100)
return jsonify(entity)
@app.route('/api/analyze', methods=['POST'])
def analyze_entity():
data = request.json
entity_type = data.get('type')
severity = data.get('severity')
prompt = f"""
You are the AI Core of the 'Ocean Guard' autonomous marine drone.
Detected Entity: {entity_type}
Severity: {severity}
Analyze the situation and decide the best action.
Available Actions:
1. 'deploy_cleanup': For debris/pollution.
2. 'deploy_patrol': For illegal activities.
3. 'log_observation': For wildlife/nature.
4. 'emergency_alert': For critical threats.
Output strictly in JSON format:
{{
"analysis": "Markdown formatted analysis. Use bold for key terms.",
"recommended_action": "action_code",
"confidence": 0.95
}}
"""
try:
headers = {
"Authorization": f"Bearer {SILICON_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": SILICON_MODEL,
"messages": [
{"role": "system", "content": "You are a marine ecology AI assistant. Output JSON only."},
{"role": "user", "content": prompt}
],
"temperature": 0.3
}
# Fast timeout for mock fallback
response = requests.post(SILICON_URL, json=payload, headers=headers, timeout=8)
response.raise_for_status()
result = response.json()['choices'][0]['message']['content']
# Clean JSON markdown
if "```json" in result:
result = result.split("```json")[1].split("```")[0].strip()
elif "```" in result:
result = result.split("```")[1].strip()
return jsonify(json.loads(result))
except Exception as e:
print(f"LLM Error: {e}")
# Mock Fallback
mock_response = {
"analysis": f"**Autonomous Protocol Engaged**\n\nConnection to central command unstable. Analyzing locally.\n\nDetected: **{entity_type}**\nSeverity: {severity}\n\nStandard procedure indicates immediate intervention or logging based on entity type.",
"recommended_action": "log_observation",
"confidence": 0.88
}
if "Plastic" in entity_type or "Net" in entity_type:
mock_response["recommended_action"] = "deploy_cleanup"
elif "Trawler" in entity_type or "Oil" in entity_type:
mock_response["recommended_action"] = "deploy_patrol"
elif "Whale" in entity_type or "Turtle" in entity_type:
mock_response["recommended_action"] = "log_observation"
return jsonify(mock_response)
@app.route('/api/execute', methods=['POST'])
def execute_action():
data = request.json
action = data.get('action')
entity = data.get('entity')
time.sleep(1) # Sim delay
# Logic for credits
credits_earned = 0
if action == 'deploy_cleanup':
credits_earned = random.uniform(8.0, 25.0)
message = "Cleanup Drone dispatched. Debris collected and recycled."
elif action == 'deploy_patrol':
credits_earned = random.uniform(15.0, 30.0)
message = "Coast Guard notified. Evidence package uploaded."
elif action == 'log_observation':
credits_earned = random.uniform(2.0, 5.0)
message = "Species data cataloged. Biodiversity contribution recorded."
elif action == 'emergency_alert':
credits_earned = random.uniform(1.0, 3.0)
message = "Emergency broadcast sent to all nearby vessels."
else:
message = "Action executed."
# Persist
db = get_db()
db.execute('INSERT INTO logs (event, action, result) VALUES (?, ?, ?)',
(f"Detected {entity}", action, message))
if credits_earned > 0:
db.execute('INSERT INTO assets (type, value) VALUES (?, ?)',
('Blue Carbon Credit', credits_earned))
db.commit()
return jsonify({
"status": "success",
"message": message,
"credits_earned": round(credits_earned, 2)
})
@app.route('/api/stats', methods=['GET'])
def get_stats():
db = get_db()
total_credits = db.execute('SELECT SUM(value) FROM assets').fetchone()[0] or 0
recent_logs = db.execute('SELECT * FROM logs ORDER BY id DESC LIMIT 10').fetchall()
logs_list = []
for log in recent_logs:
logs_list.append({
"time": log['timestamp'],
"event": log['event'],
"action": log['action'],
"result": log['result']
})
return jsonify({
"total_credits": round(total_credits, 2),
"recent_logs": logs_list
})
@app.route('/api/market', methods=['GET'])
def get_market_data():
# Simulate market trend for carbon credits
now = datetime.now()
labels = []
data = []
price = 45.0 # Base price
for i in range(12):
t = now - timedelta(hours=11-i)
labels.append(t.strftime("%H:00"))
change = random.uniform(-2.0, 3.0)
price += change
data.append(round(price, 2))
return jsonify({
"labels": labels,
"data": data,
"current_price": round(price, 2)
})
@app.route('/api/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return jsonify({"error": "No file part"}), 400
file = request.files['file']
if file.filename == '':
return jsonify({"error": "No selected file"}), 400
if file:
filename = secure_filename(file.filename)
# In a real app, save it. Here we simulate processing.
# file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
# Simulate AI processing of the image
time.sleep(1.5)
return jsonify({
"status": "success",
"message": f"File '{filename}' analyzed successfully. No anomalies detected in satellite imagery."
})
if __name__ == '__main__':
init_db()
# Ensure robust running on HF
app.run(host='0.0.0.0', port=7860)