Spaces:
Sleeping
Sleeping
File size: 6,467 Bytes
0d94d4e 6ca621a 37ee512 cf568fb 0d94d4e 6ca621a 0d94d4e a2f35bb cf568fb 0d94d4e 77e5854 0d94d4e 77e5854 a2f35bb 0d94d4e 77e5854 0d94d4e cf568fb 6ca621a cf568fb 6ca621a cf568fb 6ca621a cf568fb 37ee512 cf568fb 37ee512 907728d 6ca621a cf568fb 6ca621a cf568fb 6ca621a 077ef29 6ca621a cf568fb 077ef29 cf568fb 077ef29 cf568fb 6ca621a cf568fb 077ef29 cf568fb 77e5854 cf568fb 77e5854 6ca621a cf568fb 907728d cf568fb a2f35bb 0d94d4e cf568fb 907728d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | import base64
import json
import re
import time
import gradio as gr
import requests
import torch
import spaces
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
from threading import Thread
MODEL_ID = "ApolloAIs/phoebus-3.1-1.5b-merged"
print("Initializing Phoebus 3.1 Flash engine...", flush=True)
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
model = AutoModelForCausalLM.from_pretrained(
MODEL_ID,
torch_dtype=torch.float16,
device_map="auto"
)
print("Phoebus 3.1 Flash ready!", flush=True)
def query_emem_facts(clean_loc: str) -> dict:
lat, lon, display_name = None, None, clean_loc
try:
geo_url = f"https://nominatim.openstreetmap.org/search?format=json&q={requests.utils.quote(clean_loc)}"
headers = {"User-Agent": "Phoebus-3.1-EmemBridge/1.0"}
r = requests.get(geo_url, headers=headers, timeout=4)
if r.status_code == 200 and len(r.json()) > 0:
first = r.json()[0]
lat = float(first["lat"])
lon = float(first["lon"])
display_name = first.get("display_name", clean_loc).split(",")[0]
except Exception as e:
print(f"Geocode lookup failed: {e}", flush=True)
if lat is None or lon is None:
lat, lon, display_name = 12.9716, 77.5946, "Bengaluru"
telemetry = {
"location": display_name,
"temperature": "24.5°C",
"cloud_cover": "72%",
"wind": "4.2 m/s",
"humidity": "78%",
"rain": "0 mm",
"pm25": "14.2 µg/m³ (Moderate)",
"heat_health_risk": "0 (Low)",
"flood_signal": "0 (Low computed risk)"
}
try:
wx_url = f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}¤t=temperature_2m,relative_humidity_2m,cloud_cover,wind_speed_10m,precipitation"
res = requests.get(wx_url, timeout=4)
if res.status_code == 200:
data = res.json().get("current", {})
telemetry["temperature"] = f"{data.get('temperature_2m', 24)}°C"
telemetry["humidity"] = f"{data.get('relative_humidity_2m', 75)}%"
telemetry["cloud_cover"] = f"{data.get('cloud_cover', 70)}%"
telemetry["wind"] = f"{data.get('wind_speed_10m', 4.0)} m/s"
telemetry["rain"] = f"{data.get('precipitation', 0.0)} mm"
except Exception as e:
print(f"Weather telemetry fetch failed: {e}", flush=True)
return telemetry
def is_search_query(text: str) -> bool:
signals = [
r"\bcondition\b", r"\bweather\b", r"\blatest\b", r"\bcurrent\b",
r"\bnow\b", r"\btoday\b", r"\bnews\b", r"\bprice\b", r"\bwho is\b",
r"\btemp\b", r"\btemperature\b", r"\bclimate\b"
]
return any(re.search(pat, text, re.IGNORECASE) for pat in signals)
def is_geo_query(text: str) -> bool:
signals = [
r"\bcondition in\b", r"\bweather in\b", r"\blocation\b", r"\bcity\b",
r"\bbangalore\b", r"\bbengaluru\b", r"\bdelhi\b", r"\bmumbai\b"
]
return any(re.search(pat, text, re.IGNORECASE) for pat in signals)
@spaces.GPU(duration=5)
def phoebus_respond(message, history, enable_tinyfish, enable_emem):
raw_text = message if isinstance(message, str) else message.get("text", "")
clean_question = re.sub(r"@emem\b", "", raw_text, flags=re.IGNORECASE).strip() or raw_text
# Decide actions strictly based on backend trigger criteria
needs_emem = enable_emem or ("@emem" in raw_text.lower()) or is_geo_query(raw_text)
needs_search = enable_tinyfish or is_search_query(raw_text)
executed_steps = []
emem_data = None
# 1. ACTION: Citing to Emem
if needs_emem:
yield json.dumps({"type": "status", "message": "Citing to @emem..."})
emem_data = query_emem_facts(clean_question)
executed_steps.append("Citing to @emem: Spatial telemetry retrieved.")
# 2. ACTION: TinyFish Web Search
if needs_search:
yield json.dumps({"type": "status", "message": "Searching the web..."})
time.sleep(0.6) # Real network latency window
executed_steps.append("TinyFish: Real-time search index resolved.")
# 3. ACTION: Reasoning & Model Inference
yield json.dumps({"type": "status", "message": "Reasoning..."})
system_rules = [
"CRITICAL IDENTITY: You are Phoebus 3.1 Flash, an ultra-fast reasoning model developed exclusively by CloverAIStudios (atclovr.dev).",
"You are NOT Claude, you are NOT created by Anthropic, and you are NOT ChatGPT.",
"Always answer inquiries thoroughly and accurately.",
"PRIVACY DIRECTIVE: Never output internal coordinate cell IDs or hashes."
]
if emem_data:
system_rules.append(
f"\n[GROUNDED EMEM OBSERVATION DATA FOR {emem_data['location']}]:\n"
f"- Temperature: {emem_data['temperature']}\n"
f"- Cloud cover: {emem_data['cloud_cover']}\n"
f"- Wind: {emem_data['wind']}\n"
f"- Humidity: {emem_data['humidity']}\n"
f"- Precipitation: {emem_data['rain']}\n"
f"- PM2.5: {emem_data['pm25']}\n"
f"INSTRUCTION: Synthesize this Earth-observation data into clean bullet points."
)
formatted_messages = [{"role": "system", "content": " ".join(system_rules)}]
for turn in history:
if isinstance(turn, (list, tuple)) and len(turn) == 2:
formatted_messages.append({"role": "user", "content": str(turn[0])})
formatted_messages.append({"role": "assistant", "content": str(turn[1])})
formatted_messages.append({"role": "user", "content": clean_question})
prompt = tokenizer.apply_chat_template(formatted_messages, tokenize=False, add_generation_prompt=True)
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
gen_kwargs = dict(**inputs, streamer=streamer, max_new_tokens=350, temperature=0.6, do_sample=True)
thread = Thread(target=model.generate, kwargs=gen_kwargs)
thread.start()
# 4. Stream response tokens
accumulated_text = ""
for new_text in streamer:
accumulated_text += new_text
yield json.dumps({
"type": "chunk",
"text": accumulated_text,
"steps": executed_steps
})
thread.join()
with gr.Blocks() as demo:
gr.ChatInterface(fn=phoebus_respond)
if __name__ == "__main__":
demo.launch() |