Tim Luka Horstmann
commited on
Commit
·
7ee889e
1
Parent(s):
a3b349c
Additional context
Browse files- app.py +60 -0
- stations_extra.json +13 -0
app.py
CHANGED
|
@@ -189,6 +189,57 @@ except Exception as e:
|
|
| 189 |
logger.error(f"Error loading cv_text.txt: {str(e)}")
|
| 190 |
raise
|
| 191 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
async def stream_response(query, history, game_context=None, mode: Optional[str] = None):
|
| 193 |
"""Main streaming response function that routes to either Gemini or local model"""
|
| 194 |
if USE_GEMINI:
|
|
@@ -207,6 +258,7 @@ def _format_game_context_for_prompt(game_context: Optional[Union[str, Dict[str,
|
|
| 207 |
return f"\nGAME CONTEXT: The player is currently at a station about {game_context}."
|
| 208 |
if isinstance(game_context, dict):
|
| 209 |
current = game_context.get('current_station') or game_context.get('station') or ''
|
|
|
|
| 210 |
visited = game_context.get('visited_stations') or []
|
| 211 |
context = game_context.get('context') or game_context.get('current_context') or ''
|
| 212 |
parts = ["\nGAME CONTEXT:"]
|
|
@@ -214,6 +266,14 @@ def _format_game_context_for_prompt(game_context: Optional[Union[str, Dict[str,
|
|
| 214 |
parts.append(f"Current station: {current}.")
|
| 215 |
if context:
|
| 216 |
parts.append(f"Station details: {context}.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 217 |
if visited:
|
| 218 |
try:
|
| 219 |
uniq = []
|
|
|
|
| 189 |
logger.error(f"Error loading cv_text.txt: {str(e)}")
|
| 190 |
raise
|
| 191 |
|
| 192 |
+
# Optional: Load additional station info (admin-editable) from JSON
|
| 193 |
+
STATION_EXTRAS_BY_NAME: Dict[str, str] = {}
|
| 194 |
+
STATION_EXTRAS_BY_ID: Dict[str, str] = {}
|
| 195 |
+
try:
|
| 196 |
+
extra_path = os.path.join(os.path.dirname(__file__), 'stations_extra.json')
|
| 197 |
+
if os.path.exists(extra_path):
|
| 198 |
+
with open(extra_path, 'r', encoding='utf-8') as f:
|
| 199 |
+
extra_data = json.load(f)
|
| 200 |
+
# Accept either mapping format or list of entries
|
| 201 |
+
if isinstance(extra_data, dict):
|
| 202 |
+
# by_name or by_id mapping
|
| 203 |
+
by_name = extra_data.get('by_name') or {}
|
| 204 |
+
by_id = extra_data.get('by_id') or {}
|
| 205 |
+
if isinstance(by_name, dict):
|
| 206 |
+
for k, v in by_name.items():
|
| 207 |
+
if isinstance(k, str) and isinstance(v, str):
|
| 208 |
+
STATION_EXTRAS_BY_NAME[k.strip().lower()] = v.strip()
|
| 209 |
+
if isinstance(by_id, dict):
|
| 210 |
+
for k, v in by_id.items():
|
| 211 |
+
if isinstance(k, str) and isinstance(v, str):
|
| 212 |
+
STATION_EXTRAS_BY_ID[k.strip().lower()] = v.strip()
|
| 213 |
+
# Also support {"stations": [{"id":..., "name":..., "extra":...}]}
|
| 214 |
+
stations = extra_data.get('stations') or []
|
| 215 |
+
if isinstance(stations, list):
|
| 216 |
+
for item in stations:
|
| 217 |
+
if not isinstance(item, dict):
|
| 218 |
+
continue
|
| 219 |
+
name = (item.get('name') or '').strip().lower()
|
| 220 |
+
sid = (item.get('id') or '').strip().lower()
|
| 221 |
+
extra = (item.get('extra') or '').strip()
|
| 222 |
+
if name and extra:
|
| 223 |
+
STATION_EXTRAS_BY_NAME[name] = extra
|
| 224 |
+
if sid and extra:
|
| 225 |
+
STATION_EXTRAS_BY_ID[sid] = extra
|
| 226 |
+
elif isinstance(extra_data, list):
|
| 227 |
+
for item in extra_data:
|
| 228 |
+
if not isinstance(item, dict):
|
| 229 |
+
continue
|
| 230 |
+
name = (item.get('name') or '').strip().lower()
|
| 231 |
+
sid = (item.get('id') or '').strip().lower()
|
| 232 |
+
extra = (item.get('extra') or '').strip()
|
| 233 |
+
if name and extra:
|
| 234 |
+
STATION_EXTRAS_BY_NAME[name] = extra
|
| 235 |
+
if sid and extra:
|
| 236 |
+
STATION_EXTRAS_BY_ID[sid] = extra
|
| 237 |
+
logger.info(f"Loaded station extras: {len(STATION_EXTRAS_BY_NAME)} by name, {len(STATION_EXTRAS_BY_ID)} by id")
|
| 238 |
+
else:
|
| 239 |
+
logger.info("No stations_extra.json found; skipping extras")
|
| 240 |
+
except Exception as e:
|
| 241 |
+
logger.warning(f"Failed to load stations_extra.json: {e}")
|
| 242 |
+
|
| 243 |
async def stream_response(query, history, game_context=None, mode: Optional[str] = None):
|
| 244 |
"""Main streaming response function that routes to either Gemini or local model"""
|
| 245 |
if USE_GEMINI:
|
|
|
|
| 258 |
return f"\nGAME CONTEXT: The player is currently at a station about {game_context}."
|
| 259 |
if isinstance(game_context, dict):
|
| 260 |
current = game_context.get('current_station') or game_context.get('station') or ''
|
| 261 |
+
current_id = game_context.get('current_station_id') or ''
|
| 262 |
visited = game_context.get('visited_stations') or []
|
| 263 |
context = game_context.get('context') or game_context.get('current_context') or ''
|
| 264 |
parts = ["\nGAME CONTEXT:"]
|
|
|
|
| 266 |
parts.append(f"Current station: {current}.")
|
| 267 |
if context:
|
| 268 |
parts.append(f"Station details: {context}.")
|
| 269 |
+
# Look up admin-provided extras
|
| 270 |
+
extra_text = ''
|
| 271 |
+
if current_id:
|
| 272 |
+
extra_text = STATION_EXTRAS_BY_ID.get(str(current_id).strip().lower(), '')
|
| 273 |
+
if not extra_text and current:
|
| 274 |
+
extra_text = STATION_EXTRAS_BY_NAME.get(str(current).strip().lower(), '')
|
| 275 |
+
if extra_text:
|
| 276 |
+
parts.append(f"Additional station notes: {extra_text}")
|
| 277 |
if visited:
|
| 278 |
try:
|
| 279 |
uniq = []
|
stations_extra.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"stations": [
|
| 3 |
+
{ "id": "sge", "name": "Abitur – Städtisches Gymnasium Erwitte", "extra": "Während meiner Zeit in meiner Heimatstadt Erwitte habe ich über verschiedene Zeiträume hinweg Fußball, Tennis, Tischtennis, und Baseball im Verein gespielt. Ich war sogar Tischtennis-Trainer und habe damit Geld verdient." },
|
| 4 |
+
{ "id": "hsrm", "name": "RheinMain University of Applied Sciences", "extra": "" },
|
| 5 |
+
{ "id": "continental", "name": "Continental AG", "extra": "" },
|
| 6 |
+
{ "id": "amazon", "name": "Amazon", "extra": "" },
|
| 7 |
+
{ "id": "mckinsey", "name": "McKinsey & Company", "extra": "" },
|
| 8 |
+
{ "id": "cambridge", "name": "University of Cambridge", "extra": "" },
|
| 9 |
+
{ "id": "ip-paris", "name": "Institut Polytechnique de Paris", "extra": "" },
|
| 10 |
+
{ "id": "hi_paris", "name": "Hi! PARIS", "extra": "" }
|
| 11 |
+
]
|
| 12 |
+
}
|
| 13 |
+
|