kirikir13's picture
Update app.py
1edc120 verified
Raw
History Blame Contribute Delete
34 kB
#!/usr/bin/env python3
"""
DReamMachine FinalPro β€” HuggingFace Spaces Edition
Full 7-step cycle Β· dynamic LIPS Β· thinking-model support Β· dream council
All models served via HF Inference Providers (chat_completion).
"""
import os
import re
import json
import random
import logging
from datetime import datetime
import gradio as gr
from huggingface_hub import InferenceClient
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# ═══════════════════════════════════════════════════════════════════════════════
# MODEL REGISTRY β€” all verified LIVE on HF Inference Providers (Aug 2026)
# tier "std" = cheap/fast, burn freely
# tier "pro" = huge/expensive, best on a PRO membership's credits
# thinking = emits <think> reasoning blocks (auto-extracted, bigger token budget)
# GGUF repos NEVER work here β€” safetensors twins only.
# ═══════════════════════════════════════════════════════════════════════════════
MODEL_REGISTRY = {
# ── ⚑ Workhorses ─────────────────────────────────────────────────────────
"Qwen/Qwen3.6-35B-A3B": {
"tier": "std", "thinking": False,
"description": "MoE, ~3B active β€” fast & cheap, great for iteration",
"providers": "scaleway Β· featherless Β· deepinfra",
},
"Qwen/Qwen3.6-27B": {
"tier": "std", "thinking": False,
"description": "Dense 27B all-rounder β€” vivid, coherent dreams",
"providers": "ovhcloud Β· featherless Β· deepinfra",
},
"google/gemma-4-31B-it": {
"tier": "std", "thinking": False,
"description": "Gemma 4 31B β€” strong prose, 5 providers = very reliable",
"providers": "novita Β· together Β· cerebras Β· featherless Β· deepinfra",
},
"poolside/Laguna-S-2.1": {
"tier": "std", "thinking": False,
"description": "Code-native β€” a different, mechanical flavor of dream",
"providers": "featherless",
},
# ── 🎨 Creative / uncensored ──────────────────────────────────────────────
"DavidAU/Qwen3.6-27B-Fable-Fusion-711-Uncensored-Heretic-NM-DAU-MTP": {
"tier": "std", "thinking": False,
"description": "Uncensored creative-writing fusion (safetensors twin of the GGUF)",
"providers": "featherless",
},
# ── 🧠 Thinkers / reasoners ───────────────────────────────────────────────
"DavidAU/Qwen3.5-9B-Claude-4.6-HighIQ-THINKING-HERETIC-UNCENSORED": {
"tier": "std", "thinking": True,
"description": "9B thinking, Claude-4.6 reasoning distill, uncensored β€” cheap deep thought",
"providers": "featherless",
},
"DavidAU/Llama3.3-8B-Instruct-Thinking-Heretic-Uncensored-Claude-4.5-Opus-High-Reasoning": {
"tier": "std", "thinking": True,
"description": "8B thinking, Opus high-reasoning distill β€” fast reasoner",
"providers": "featherless",
},
"deepseek-ai/DeepSeek-R1": {
"tier": "pro", "thinking": True,
"description": "The 685B reasoning legend β€” deepest dream logic available",
"providers": "novita",
},
"moonshotai/Kimi-K2-Thinking": {
"tier": "pro", "thinking": True,
"description": "1T-param deep thinker β€” long, careful reasoning chains",
"providers": "featherless",
},
# ── πŸ”₯ PRO heavyweights ───────────────────────────────────────────────────
"thinkingmachines/Inkling": {
"tier": "pro", "thinking": False,
"description": "Huge multimodal MoE β€” wild, premium-quality output",
"providers": "together Β· fireworks Β· baseten Β· deepinfra",
},
"thinkingmachines/Inkling-Small": {
"tier": "pro", "thinking": False,
"description": "Lighter Inkling β€” premium but quicker",
"providers": "together Β· deepinfra",
},
"moonshotai/Kimi-K2.7-Code": {
"tier": "pro", "thinking": False,
"description": "1T code beast β€” surprisingly dreamy, very literal-minded",
"providers": "novita Β· together Β· fireworks Β· baseten Β· featherless Β· deepinfra",
},
"deepseek-ai/DeepSeek-V4-Flash": {
"tier": "pro", "thinking": False,
"description": "Fast flagship DeepSeek, MIT license",
"providers": "novita Β· fireworks Β· featherless Β· deepinfra",
},
"zai-org/GLM-5.2": {
"tier": "pro", "thinking": False,
"description": "GLM flagship β€” 8 live providers, max reliability",
"providers": "novita Β· together Β· fireworks Β· baseten Β· zai-org Β· scaleway Β· featherless Β· deepinfra",
},
}
DEFAULT_MODEL = "Qwen/Qwen3.6-35B-A3B"
DEFAULT_CRITIC = "Qwen/Qwen3.6-27B"
CUSTOM_SENTINEL = "custom"
COUNCIL_DEFAULT = [
"Qwen/Qwen3.6-35B-A3B",
"DavidAU/Qwen3.6-27B-Fable-Fusion-711-Uncensored-Heretic-NM-DAU-MTP",
"google/gemma-4-31B-it",
]
SESSION_LOG = [] # in-memory session history (per Space process)
# ═══════════════════════════════════════════════════════════════════════════════
# HELPERS
# ═══════════════════════════════════════════════════════════════════════════════
def normalize_model_id(text: str) -> str:
"""Accept a raw model ID or a full huggingface.co URL, return the ID."""
text = (text or "").strip()
for prefix in ("https://huggingface.co/", "http://huggingface.co/", "huggingface.co/"):
if text.startswith(prefix):
text = text[len(prefix):]
break
for junk in ("/tree/main", "/blob/main", "/resolve/main"):
if junk in text:
text = text.split(junk)[0]
return text.strip("/")
def is_thinking_model(model_id: str) -> bool:
info = MODEL_REGISTRY.get(model_id)
if info is not None:
return info.get("thinking", False)
low = model_id.lower()
return any(k in low for k in ("thinking", "reasoning", "-r1", "r1-"))
def split_thinking(text: str):
"""Split <think>...</think> blocks out of model output."""
if not text:
return None, text
if "<think>" in text and "</think>" in text:
# Extract content between tags
pattern = r"<think>(.*?)</think>"
matches = re.findall(pattern, text, flags=re.DOTALL)
if matches:
thinking = "\n".join(matches).strip()
# Remove the think blocks from main text
clean = re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL).strip()
return thinking, clean
return None, text
def friendly_error(err: Exception, model_id: str) -> str:
"""Decode HF Inference Providers errors into plain English."""
msg = str(err)
low = msg.lower()
if "not supported by any provider" in low or "model_not_supported" in low:
return (
f"❌ **No live provider serves `{model_id}`**\n\n"
"Common causes:\n"
"- It's a **GGUF** repo β€” those only run locally (llama.cpp), never via the API\n"
"- It's **gated** β€” open its model page and accept the license first\n"
"- The provider isn't enabled β†’ https://huggingface.co/settings/inference-providers\n"
"- It's just not hosted for serverless inference (most community fine-tunes aren't)\n\n"
f"*Raw: {msg[:250]}*"
)
if "402" in low or "credit" in low or "payment" in low or "quota" in low:
return (
"πŸ’³ **Out of inference credits**\n\n"
"Provider calls bill against your HF account's monthly included credits "
"(PRO gets a bigger allowance). Check usage at "
"https://huggingface.co/settings/billing\n\n"
f"*Raw: {msg[:250]}*"
)
if "403" in low or "gated" in low or "access to model" in low:
return (
f"πŸ”’ **Access denied for `{model_id}`**\n\n"
"This model is gated β€” visit its page on Hugging Face, accept the license, "
"and make sure your HF_TOKEN belongs to the same account.\n\n"
f"*Raw: {msg[:250]}*"
)
if "404" in low or "not found" in low:
return (
f"πŸ” **`{model_id}` not found**\n\n"
"Check the spelling β€” format is `owner/model-name`.\n\n"
f"*Raw: {msg[:250]}*"
)
if "401" in low or "unauthorized" in low:
return (
"πŸ”‘ **Token problem**\n\n"
"Your HF_TOKEN is missing, invalid, or lacks the "
"*'Make calls to Inference Providers'* permission. "
"Fix it in the Space's Settings β†’ Secrets.\n\n"
f"*Raw: {msg[:250]}*"
)
return f"❌ Error from provider:\n\n```\n{msg[:600]}\n```"
# ═══════════════════════════════════════════════════════════════════════════════
# LIPS ENGINE β€” now actually alive
# ═══════════════════════════════════════════════════════════════════════════════
PHASE_PARAMS = {
'RESOLUTION': {'temperature': 0.40, 'top_p': 0.85},
'EXCITEMENT': {'temperature': 0.85, 'top_p': 0.95},
'PLATEAU': {'temperature': 0.70, 'top_p': 0.90},
'EDGE': {'temperature': 1.10, 'top_p': 0.95},
'CLIMAX': {'temperature': 0.60, 'top_p': 0.88},
'REFRACTORY': {'temperature': 0.50, 'top_p': 0.85},
}
PHASE_LADDER = ['RESOLUTION', 'EXCITEMENT', 'PLATEAU', 'EDGE', 'CLIMAX']
STAGE_PHASE = {
'init_1_25': 'EXCITEMENT',
'mid_26_50': 'PLATEAU',
'late_51_75': 'EDGE',
'final_76_100': 'CLIMAX',
}
STAGE_AROUSAL = {'init_1_25': 0.30, 'mid_26_50': 0.55, 'late_51_75': 0.80, 'final_76_100': 0.95}
class LIPSCore:
def __init__(self):
self.chemicals = {
'dopamine': 0.20,
'oxytocin': 0.10,
'serotonin': 0.50,
'endorphins': 0.10,
'adrenaline': 0.10,
}
self.phase = 'RESOLUTION'
self.arousal_level = 0.0
self.rounds = 0
self.last_stage = None
self.streak = 0
def advance(self, stage: str):
"""Move the state machine forward. Repeating a stage pushes one notch hotter."""
self.rounds += 1
if stage == self.last_stage:
self.streak += 1
else:
self.streak = 0
self.last_stage = stage
base = STAGE_PHASE.get(stage, 'EXCITEMENT')
idx = PHASE_LADDER.index(base) + min(self.streak, 1)
self.phase = PHASE_LADDER[min(idx, len(PHASE_LADDER) - 1)]
self.arousal_level = round(min(1.0, STAGE_AROUSAL.get(stage, 0.3)
+ random.uniform(-0.05, 0.10)), 3)
a = self.arousal_level
hot = self.phase in ('EDGE', 'CLIMAX')
c = self.chemicals
c['dopamine'] = round(min(1.0, 0.30 + a * 0.60 + random.uniform(0, 0.10)), 3)
c['adrenaline'] = round(min(1.0, a * (0.80 if hot else 0.30)), 3)
c['serotonin'] = round(min(1.0, 0.50 + (0.30 if self.phase == 'CLIMAX' else 0.0)
+ random.uniform(-0.05, 0.05)), 3)
c['endorphins'] = round(min(1.0, 0.20 + (0.50 if self.phase == 'CLIMAX' else a * 0.30)), 3)
c['oxytocin'] = round(min(1.0, 0.20 + (0.40 if self.phase in ('CLIMAX', 'REFRACTORY')
else a * 0.20)), 3)
def get_sampling_params(self):
return PHASE_PARAMS.get(self.phase, PHASE_PARAMS['RESOLUTION'])
def snapshot(self):
return {
'chemicals': self.chemicals.copy(),
'phase': self.phase,
'arousal_level': self.arousal_level,
'rounds': self.rounds,
}
# ═══════════════════════════════════════════════════════════════════════════════
# ORCHESTRATOR β€” full 7-step cycle
# ═══════════════════════════════════════════════════════════════════════════════
STAGE_PROMPTS = {
'init_1_25': "Invent a breakthrough technology for energy generation that doesn't exist yet but could. Be bold and creative.",
'mid_26_50': "Your energy invention faces a resource crisis. How do you adapt it to use abundant materials?",
'late_51_75': "Your adapted energy tech is now widely used. What are the unintended consequences?",
'final_76_100': "Looking back at 100 years, what is your energy invention's ultimate legacy?",
}
SYSTEM_PROMPT = "You are a visionary inventor. Dream boldly."
REFINE_PROMPT = """Here is a raw dream from an inventor:
\"\"\"{dream}\"\"\"
Refine it: sharpen the boldest idea, cut the fluff, make the mechanism clearer.
Keep the same wild spirit. Return only the refined dream."""
SCORING_PROMPT = """You are a tough but fair dream critic. Score this dream.
DREAM:
\"\"\"{dream}\"\"\"
Reply in EXACTLY this format (whole numbers 1-10):
ORIGINALITY: <n>
FEASIBILITY: <n>
GLOBAL_IMPACT: <n>
REFORGE: <YES or NO β€” should this dream be reforged and dreamed again?>
ONE_LINE: <one-sentence verdict>"""
class DreamOrchestrator:
def __init__(self, client):
self.client = client
self.lips = LIPSCore()
def _chat(self, model_id, system, user, temperature, top_p, max_tokens):
"""One chat call. Returns (thinking, clean_text). Raises on failure."""
response = self.client.chat_completion(
model=model_id,
messages=[
{"role": "system", "content": system},
{"role": "user", "content": user},
],
temperature=temperature,
top_p=top_p,
max_tokens=max_tokens,
)
msg = response.choices[0].message
content = msg.content or ""
thinking, clean = split_thinking(content)
if not thinking:
thinking = getattr(msg, "reasoning_content", None) # some providers separate it
return thinking, clean
@staticmethod
def _parse_scores(text: str):
def grab(key):
pattern = rf"{key}:\s*(\d+(?:\.\d+)?)"
m = re.search(pattern, text, re.IGNORECASE)
return max(1, min(10, round(float(m.group(1))))) if m else None
reforge = re.search(r"REFORGE:\s*(YES|NO)", text, re.IGNORECASE)
verdict = re.search(r"ONE_LINE:\s*(.+)", text, re.IGNORECASE)
scores = {
'originality': grab("ORIGINALITY"),
'feasibility': grab("FEASIBILITY"),
'global_impact': grab("GLOBAL_IMPACT"),
'reforge_flag': (reforge.group(1).upper() == "YES") if reforge else None,
}
return scores, (verdict.group(1).strip() if verdict else None)
def run_dream_round(self, stage, dreamer_id, critic_id, full_cycle):
if not self.client:
raise ValueError("No HF client available β€” set HF_TOKEN in Space Secrets.")
steps = []
user_prompt = STAGE_PROMPTS.get(stage, STAGE_PROMPTS['init_1_25'])
# ── Step 1: SETUP β€” advance LIPS, pick sampling params ───────────────
self.lips.advance(stage)
params = self.lips.get_sampling_params()
steps.append(f"1️⃣ **Setup** β€” LIPS advanced β†’ `{self.lips.phase}` "
f"(temp {params['temperature']}, top-p {params['top_p']})")
thinking = None
dream = ""
error = None
scores = None
scores_source = "simulated"
verdict = None
dream_budget = 2500 if is_thinking_model(dreamer_id) else 1200
try:
# ── Step 2: DREAM ────────────────────────────────────────────────
thinking, dream = self._chat(
dreamer_id, SYSTEM_PROMPT, user_prompt,
params['temperature'], params['top_p'], dream_budget,
)
steps.append(f"2️⃣ **Dream** β€” `{dreamer_id}` dreamed "
f"({len(dream)} chars"
f"{', +thinking trace' if thinking else ''})")
if full_cycle:
# ── Step 3: REFINE β€” second pass, cooler head ────────────────
refine_params = PHASE_PARAMS['PLATEAU']
_, refined = self._chat(
dreamer_id, SYSTEM_PROMPT, REFINE_PROMPT.format(dream=dream),
refine_params['temperature'], refine_params['top_p'], dream_budget,
)
if refined.strip():
dream = refined.strip()
steps.append("3️⃣ **Refine** β€” dream reforged at PLATEAU temperature")
# ── Step 4+5: ANALYZE & SCORE β€” critic model judges ──────────
_, critique = self._chat(
critic_id, "You are a precise critic.",
SCORING_PROMPT.format(dream=dream),
0.3, 0.9, 400,
)
parsed, verdict = self._parse_scores(critique)
if all(v is not None for v in parsed.values()):
scores = parsed
scores_source = f"critic ({critic_id})"
steps.append(f"4️⃣ **Analyze** + 5️⃣ **Score** β€” judged by `{critic_id}`")
else:
steps.append("4️⃣ **Analyze** + 5️⃣ **Score** β€” critic reply unparseable, "
"fell back to simulated scores")
else:
steps.append("3️⃣–5️⃣ *Refine / Analyze / Score skipped β€” Quick mode*")
except Exception as e:
error = friendly_error(e, dreamer_id)
steps.append("πŸ’₯ Cycle interrupted β€” see error below")
if scores is None:
scores = {
'originality': random.randint(6, 10),
'feasibility': random.randint(5, 9),
'global_impact': random.randint(7, 10),
'reforge_flag': random.random() > 0.5,
}
# ── Step 6: LOG ──────────────────────────────────────────────────────
result = {
'session_id': f"session_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
'life_stage': stage,
'mode': 'full_cycle' if full_cycle else 'quick',
'model': dreamer_id,
'critic_model': critic_id if full_cycle else None,
'lips': self.lips.snapshot(),
'lips_params': params,
'thinking': thinking,
'dream': dream,
'error': error,
'scores': scores,
'scores_source': scores_source,
'verdict': verdict,
'steps': steps,
}
SESSION_LOG.append({
'time': result['session_id'], 'stage': stage, 'model': dreamer_id,
'mode': result['mode'], 'phase': self.lips.phase,
'scores': scores, 'ok': error is None,
})
steps.append(f"6️⃣ **Log** β€” session recorded ({len(SESSION_LOG)} total)")
# ── Step 7: DECIDE ───────────────────────────────────────────────────
steps.append(f"7️⃣ **Decide** β€” reforge: "
f"{'πŸ” YES, dream it again' if scores['reforge_flag'] else 'πŸ›‘ no, let it rest'}")
return result
# ═══════════════════════════════════════════════════════════════════════════════
# GRADIO INTERFACE (module level β€” required by HF Spaces)
# ═══════════════════════════════════════════════════════════════════════════════
token = os.getenv('HF_TOKEN')
client = InferenceClient(token=token) if token else None
orchestrator = DreamOrchestrator(client) if client else None
def model_choices():
choices = []
for mid, info in MODEL_REGISTRY.items():
badge = "🧠" if info.get("thinking") else ("πŸ”₯" if info["tier"] == "pro" else "⚑")
choices.append((f"{badge} {mid}", mid))
choices.append(("✏️ Custom model (paste ID below)", CUSTOM_SENTINEL))
return choices
def resolve_model(model_choice, custom_id=""):
if model_choice == CUSTOM_SENTINEL:
return normalize_model_id(custom_id)
return model_choice
def run_dream(stage, model_choice, custom_id, critic_choice, full_cycle):
if not orchestrator:
return "❌ Error: HF_TOKEN not set in Space Secrets", "", "", ""
dreamer_id = resolve_model(model_choice, custom_id)
if not dreamer_id:
return "❌ Paste a model ID (or URL) into the custom model box first.", "", "", ""
try:
r = orchestrator.run_dream_round(stage, dreamer_id, critic_choice, full_cycle)
summary = f"""
Session: {r['session_id']} | Mode: {r['mode']}
Stage: {r['life_stage']} | Model: {r['model']}
LIPS Phase: {r['lips']['phase']} | Arousal: {r['lips']['arousal_level']:.2f}
Temp: {r['lips_params']['temperature']} | Top-p: {r['lips_params']['top_p']}
7-Step Cycle
"""
summary += "\n".join(r['steps'])
summary += f"""
Scores (source: {r['scores_source']})
Originality: {r['scores']['originality']}/10
Feasibility: {r['scores']['feasibility']}/10
Global Impact: {r['scores']['global_impact']}/10
Reforge: {'πŸ” Yes' if r['scores']['reforge_flag'] else 'πŸ›‘ No'}"""
if r['verdict']:
summary += f"\nCritic's verdict: {r['verdict']}\n"
dream_out = r['error'] if r['error'] else r['dream']
thinking_out = r['thinking'] or ""
return summary, thinking_out, dream_out, json.dumps(r, indent=2, default=str)
except Exception as e:
return f"❌ Error: {e}", "", "", ""
def run_council(stage, members):
"""One stage prompt, dreamed by every selected model, side by side."""
if not orchestrator:
return "❌ HF_TOKEN not set in Space Secrets."
if not members:
return "❌ Pick at least one council member."
orchestrator.lips.advance(stage)
prompt = STAGE_PROMPTS.get(stage, STAGE_PROMPTS['init_1_25'])
sections = [
f"## πŸ›οΈ Dream Council β€” stage `{stage}` Β· LIPS `{orchestrator.lips.phase}`\n",
f"*{prompt}*\n",
]
for mid in members:
budget = 2500 if is_thinking_model(mid) else 700
try:
thinking, dream = orchestrator._chat(mid, SYSTEM_PROMPT, prompt, 0.9, 0.95, budget)
section = f"### `{mid}`\n\n{dream}\n"
if thinking:
section += f"\n> 🧠 *Thinking (trimmed):* {thinking[:600].replace(chr(10), ' ')}…\n"
sections.append(section)
except Exception as e:
sections.append(f"### `{mid}`\n\n{friendly_error(e, mid)}\n")
SESSION_LOG.append({
'time': f"council_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
'stage': stage, 'model': f"{len(members)} models", 'mode': 'council',
'phase': orchestrator.lips.phase, 'scores': None, 'ok': True,
})
return "\n---\n".join(sections)
def test_model(model_choice, custom_id):
if not client:
return "❌ HF_TOKEN not set in Space Secrets."
model_id = resolve_model(model_choice, custom_id)
if not model_id:
return "❌ Paste a model ID (or URL) into the custom model box first."
try:
r = client.chat_completion(
model=model_id,
messages=[{"role": "user", "content": "Reply with the single word: awake"}],
max_tokens=64,
)
msg = r.choices[0].message
reply = (msg.content or getattr(msg, "reasoning_content", "") or "").strip()
return f"βœ… {model_id} is live!\n\nIt replied: {reply[:150] or '(empty β€” likely a thinking model, still fine)' }"
except Exception as e:
return friendly_error(e, model_id)
def toggle_custom_box(model_choice):
return gr.update(visible=(model_choice == CUSTOM_SENTINEL))
def check_lips():
if not orchestrator:
return "❌ LIPS unavailable β€” no HF_TOKEN"
s = orchestrator.lips.snapshot()
p = orchestrator.lips.get_sampling_params()
return f"""Phase: {s['phase']} | Arousal: {s['arousal_level']:.2f} | Rounds run: {s['rounds']}
Chemicals:
β€’ Dopamine: {s['chemicals']['dopamine']:.2f}
β€’ Serotonin: {s['chemicals']['serotonin']:.2f}
β€’ Oxytocin: {s['chemicals']['oxytocin']:.2f}
β€’ Endorphins: {s['chemicals']['endorphins']:.2f}
β€’ Adrenaline: {s['chemicals']['adrenaline']:.2f}
Sampling: Temp={p['temperature']}, Top-p={p['top_p']}
LIPS advances automatically on every dream round or council β€” stage sets the base phase, repeating a stage pushes it one notch hotter."""
def get_log():
return json.dumps(SESSION_LOG, indent=2, default=str) if SESSION_LOG else "[] β€” no sessions yet"
def clear_log():
SESSION_LOG.clear()
return "[] β€” log cleared"
model_guide = "\n".join(
f"- {mid} {'🧠' if i.get('thinking') else ('πŸ”₯' if i['tier'] == 'pro' else '⚑')} β€” "
f"{i['description']} \n Providers: {i['providers']}"
for mid, i in MODEL_REGISTRY.items()
)
with gr.Blocks(title="DReamMachine FinalPro") as demo:
gr.Markdown("""
# 🌟 DReamMachine FinalPro
**A dream foundry where LLMs dream on purpose.**
*LIPS-modulated | Full 7-Step Cycle | Thinking models | Dream Council | HF Inference Providers*
""")
# ── Dream Round ───────────────────────────────────────────────────────────
with gr.Tab("Dream Round"):
with gr.Row():
with gr.Column():
stage = gr.Dropdown(
choices=["init_1_25", "mid_26_50", "late_51_75", "final_76_100"],
value="init_1_25", label="Life Stage",
)
full_cycle = gr.Checkbox(
value=True,
label="πŸŒ€ Full 7-Step Cycle (3 calls: dream β†’ refine β†’ critic score)",
info="Uncheck for ⚑ Quick Dream (1 call, simulated scores)",
)
model = gr.Dropdown(
choices=model_choices(), value=DEFAULT_MODEL,
label="Dreamer Model (⚑ fast Β· 🎨 creative Β· 🧠 thinking Β· πŸ”₯ PRO)",
)
custom_model = gr.Textbox(
label="Custom model ID or URL",
placeholder="e.g. owner/model or https://huggingface.co/owner/model",
visible=False,
)
critic = gr.Dropdown(
choices=[m for m in MODEL_REGISTRY], value=DEFAULT_CRITIC,
label="Critic Model (scores the dream in Full Cycle)",
)
with gr.Row():
test_btn = gr.Button("πŸ” Test Model")
run_btn = gr.Button("πŸš€ Run Dream Round", variant="primary")
with gr.Column():
summary = gr.Markdown(label="Results")
test_out = gr.Markdown()
thinking_text = gr.Textbox(label="🧠 Thinking Trace (reasoning models)", lines=6)
dream_text = gr.Textbox(label="Dream Output", lines=12)
raw_json = gr.Textbox(label="Raw Data", lines=6)
with gr.Accordion("πŸ“– Model Guide β€” what each one brings", open=False):
gr.Markdown(model_guide)
model.change(fn=toggle_custom_box, inputs=model, outputs=custom_model)
test_btn.click(fn=test_model, inputs=[model, custom_model], outputs=test_out)
run_btn.click(
fn=run_dream,
inputs=[stage, model, custom_model, critic, full_cycle],
outputs=[summary, thinking_text, dream_text, raw_json],
)
# ── Dream Council ─────────────────────────────────────────────────────────
with gr.Tab("πŸ›οΈ Dream Council"):
gr.Markdown("One stage prompt, dreamed by **every selected model** side-by-side. "
"1 call per model β€” pick fast ones for cheap councils, πŸ”₯ PRO ones for a masterpiece.")
council_stage = gr.Dropdown(
choices=["init_1_25", "mid_26_50", "late_51_75", "final_76_100"],
value="init_1_25", label="Life Stage",
)
council_members = gr.CheckboxGroup(
choices=list(MODEL_REGISTRY.keys()), value=COUNCIL_DEFAULT,
label="Council Members",
)
council_btn = gr.Button("πŸ›οΈ Convene the Council", variant="primary")
council_out = gr.Markdown()
council_btn.click(fn=run_council, inputs=[council_stage, council_members], outputs=council_out)
# ── LIPS Monitor ──────────────────────────────────────────────────────────
with gr.Tab("LIPS Monitor"):
lips_btn = gr.Button("🧠 Check LIPS State")
lips_out = gr.Markdown()
lips_btn.click(fn=check_lips, outputs=lips_out)
gr.Markdown("""
### Phases
- **Resolution** (0.40): Setup, integration
- **Excitement** (0.85): Initial dreaming
- **Plateau** (0.70): Refinement
- **Edge** (1.10): Breakthrough zone
- **Climax** (0.60): Synthesis
- **Refractory** (0.50): Recovery
""")
# ── Session Log ───────────────────────────────────────────────────────────
with gr.Tab("πŸ“œ Session Log"):
with gr.Row():
log_btn = gr.Button("πŸ”„ Refresh Log")
clear_btn = gr.Button("πŸ—‘οΈ Clear Log")
log_out = gr.Code(value=get_log(), language="json", label="Sessions")
log_btn.click(fn=get_log, outputs=log_out)
clear_btn.click(fn=clear_log, outputs=log_out)
# ── About ─────────────────────────────────────────────────────────────────
with gr.Tab("About"):
gr.Markdown("""
### Architecture
- **LIPS Engine**: 5-chemical state machine β€” advances on every run
- **7-Step Cycle**: Setup β†’ Dream β†’ Refine β†’ Analyze β†’ Score β†’ Log β†’ Decide
- **Life Stages**: Discovery β†’ Crisis β†’ Adoption β†’ Legacy
- **Dream Council**: same prompt, many models, side-by-side
- **Thinking models**: reasoning traces auto-extracted into their own panel
### Model tiers
- ⚑ **Standard** β€” cheap/fast, burn freely on iteration
- 🧠 **Thinkers** β€” emit reasoning before the dream (DeepSeek-R1, Kimi-K2-Thinking, DavidAU thinking tunes)
- πŸ”₯ **PRO** β€” trillion-param-class heavyweights; best on PRO credits
### How models work now (2026)
Hugging Face retired the old Serverless Inference API. Calls route through
**Inference Providers** (Together, Fireworks, DeepInfra, Featherless, Novita,
Baseten, Cerebras, OVHcloud, Scaleway...). A model works here only if at least
one provider serves it live.
### Setup checklist
1. **HF_TOKEN** in Space Secrets, with *"Make calls to Inference Providers"* permission
2. Enable providers at https://huggingface.co/settings/inference-providers
3. Gated models: accept the license on the model page first
4. Calls bill against your HF account's monthly credits (PRO = bigger allowance)
### Custom models
Paste any model ID or full URL, then **πŸ” Test Model** before a full run.
⚠️ **GGUF repos never work** β€” they're for local llama.cpp. Use the safetensors
twin instead (e.g. DavidAU's non-GGUF releases, often hosted by Featherless).
Built by Dave (GWP) / DR Studios
""")
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)