Add render.yaml, fix gemini provider routing, show LLM model in header
Browse files- render.yaml: declares LLM_PROVIDER=gemini as versioned config; secrets
(GEMINI_API_KEY, GROQ_API_KEY, etc.) listed as sync:false so they persist
from the Render dashboard without being stored in the repo
- server.py: _choose_provider() now accepts "gemini" from LLM_PROVIDER env var
- simulation.py: get_state_summary() includes llm_provider + llm_model fields
- index.html: header shows active model (e.g. β¦ 2.0-flash) with full name
as tooltip; icon varies by provider (β¦ gemini, β‘ groq, β claude, π¦ ollama)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- render.yaml +28 -0
- src/soci/api/server.py +1 -1
- src/soci/engine/simulation.py +2 -0
- web/index.html +14 -0
render.yaml
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
services:
|
| 2 |
+
- type: web
|
| 3 |
+
name: soci
|
| 4 |
+
env: python
|
| 5 |
+
buildCommand: pip install -r requirements.txt
|
| 6 |
+
startCommand: python -m uvicorn soci.api.server:app --host 0.0.0.0 --port $PORT
|
| 7 |
+
|
| 8 |
+
envVars:
|
| 9 |
+
# ββ Non-secret config (declared here, always applied on deploy) ββββββββββ
|
| 10 |
+
- key: LLM_PROVIDER
|
| 11 |
+
value: gemini # gemini | groq | claude | ollama
|
| 12 |
+
|
| 13 |
+
- key: GITHUB_STATE_BRANCH
|
| 14 |
+
value: simulation-state
|
| 15 |
+
- key: GITHUB_STATE_FILE
|
| 16 |
+
value: state/autosave.json
|
| 17 |
+
|
| 18 |
+
# ββ Secrets (values set once in Render dashboard, never stored here) βββββ
|
| 19 |
+
- key: GEMINI_API_KEY
|
| 20 |
+
sync: false
|
| 21 |
+
- key: GROQ_API_KEY
|
| 22 |
+
sync: false
|
| 23 |
+
- key: ANTHROPIC_API_KEY
|
| 24 |
+
sync: false
|
| 25 |
+
- key: GITHUB_TOKEN
|
| 26 |
+
sync: false
|
| 27 |
+
- key: GITHUB_REPO
|
| 28 |
+
sync: false
|
src/soci/api/server.py
CHANGED
|
@@ -230,7 +230,7 @@ def _choose_provider() -> str:
|
|
| 230 |
"""
|
| 231 |
# Check explicit env vars first
|
| 232 |
provider = os.environ.get("SOCI_PROVIDER", "").lower() or os.environ.get("LLM_PROVIDER", "").lower()
|
| 233 |
-
if provider in ("claude", "groq", "ollama"):
|
| 234 |
return provider
|
| 235 |
|
| 236 |
# Check if keys are available
|
|
|
|
| 230 |
"""
|
| 231 |
# Check explicit env vars first
|
| 232 |
provider = os.environ.get("SOCI_PROVIDER", "").lower() or os.environ.get("LLM_PROVIDER", "").lower()
|
| 233 |
+
if provider in ("claude", "groq", "gemini", "ollama"):
|
| 234 |
return provider
|
| 235 |
|
| 236 |
# Check if keys are available
|
src/soci/engine/simulation.py
CHANGED
|
@@ -836,6 +836,8 @@ class Simulation:
|
|
| 836 |
for aid, a in self.agents.items()
|
| 837 |
},
|
| 838 |
"active_conversations": len(self.active_conversations),
|
|
|
|
|
|
|
| 839 |
"llm_usage": self.llm.usage.summary(),
|
| 840 |
}
|
| 841 |
|
|
|
|
| 836 |
for aid, a in self.agents.items()
|
| 837 |
},
|
| 838 |
"active_conversations": len(self.active_conversations),
|
| 839 |
+
"llm_provider": getattr(self.llm, "provider", "unknown"),
|
| 840 |
+
"llm_model": getattr(self.llm, "default_model", "unknown"),
|
| 841 |
"llm_usage": self.llm.usage.summary(),
|
| 842 |
}
|
| 843 |
|
web/index.html
CHANGED
|
@@ -240,6 +240,7 @@
|
|
| 240 |
<span><span id="weather-icon"></span> <span id="weather">Sunny</span></span>
|
| 241 |
<span id="agent-count"><span class="dot green"></span> 0 agents</span>
|
| 242 |
<span id="conv-count">0 convos</span>
|
|
|
|
| 243 |
<span class="controls">
|
| 244 |
<button class="ctrl-btn" id="btn-pause" onclick="togglePause()" title="Pause/Resume">⏯</button>
|
| 245 |
<button class="ctrl-btn" id="btn-slow" onclick="setSpeed(3.0)" title="Slow">🐢</button>
|
|
@@ -2862,6 +2863,19 @@ function processStateData(data) {
|
|
| 2862 |
document.getElementById('api-calls').textContent = `API: ${cm?cm[1]:'0'}`;
|
| 2863 |
document.getElementById('cost').textContent = $m ? `$${$m[1]}` : '$0.00';
|
| 2864 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2865 |
agents = data.agents || {};
|
| 2866 |
renderPlayerPanel();
|
| 2867 |
|
|
|
|
| 240 |
<span><span id="weather-icon"></span> <span id="weather">Sunny</span></span>
|
| 241 |
<span id="agent-count"><span class="dot green"></span> 0 agents</span>
|
| 242 |
<span id="conv-count">0 convos</span>
|
| 243 |
+
<span id="llm-model" title="Active LLM model">β‘ β</span>
|
| 244 |
<span class="controls">
|
| 245 |
<button class="ctrl-btn" id="btn-pause" onclick="togglePause()" title="Pause/Resume">⏯</button>
|
| 246 |
<button class="ctrl-btn" id="btn-slow" onclick="setSpeed(3.0)" title="Slow">🐢</button>
|
|
|
|
| 2863 |
document.getElementById('api-calls').textContent = `API: ${cm?cm[1]:'0'}`;
|
| 2864 |
document.getElementById('cost').textContent = $m ? `$${$m[1]}` : '$0.00';
|
| 2865 |
|
| 2866 |
+
if (data.llm_provider && data.llm_model) {
|
| 2867 |
+
// Compact model label: strip long date suffixes and version noise
|
| 2868 |
+
let label = data.llm_model
|
| 2869 |
+
.replace(/-\d{8}$/, '') // remove trailing date e.g. -20251001
|
| 2870 |
+
.replace(/-instant$/, '') // groq suffix
|
| 2871 |
+
.replace(/^gemini-/, ''); // "gemini-2.0-flash" β "2.0-flash"
|
| 2872 |
+
const providerIcon = { gemini: 'β¦', groq: 'β‘', claude: 'β', ollama: 'π¦' };
|
| 2873 |
+
const icon = providerIcon[data.llm_provider] || 'β‘';
|
| 2874 |
+
const el = document.getElementById('llm-model');
|
| 2875 |
+
el.textContent = `${icon} ${label}`;
|
| 2876 |
+
el.title = `${data.llm_provider}: ${data.llm_model}`;
|
| 2877 |
+
}
|
| 2878 |
+
|
| 2879 |
agents = data.agents || {};
|
| 2880 |
renderPlayerPanel();
|
| 2881 |
|