Aniruddha7 commited on
Commit
b28db5f
·
verified ·
1 Parent(s): 1140593

Boot priority: resume the user's active profile instead of the env DB; redact db_url passwords on all schema endpoints

Browse files
Files changed (1) hide show
  1. Agent/worker.py +46 -6
Agent/worker.py CHANGED
@@ -18,15 +18,25 @@ app = FastAPI(title="Agent Worker")
18
  # Schema profile registry (dynamic multi-DB support)
19
  # ---------------------------------------------------------------------------
20
  try:
21
- from .schema_profile import ProfileRegistry
22
  except Exception:
23
  import Agent.schema_profile as _sp
24
  ProfileRegistry = _sp.ProfileRegistry
 
25
 
26
  SCHEMAS_DIR = os.path.join("uploads", "schemas")
27
  PROFILE_STORE_PATH = os.path.join("chat_store", "schema_profiles.json")
28
  profile_registry = ProfileRegistry(PROFILE_STORE_PATH)
29
 
 
 
 
 
 
 
 
 
 
30
  SUPPORTED_DB_SUFFIXES = {".sqlite", ".db", ".sqlite3", ".csv"}
31
 
32
 
@@ -119,7 +129,19 @@ async def startup_event():
119
  # ------------------------------------------------------------------
120
  db_url = os.environ.get("DB_CONNECTION_URL")
121
  active = profile_registry.active()
122
- target_uri = db_url or (active or {}).get("db_url") or demo_db_url
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
  if target_uri:
125
  try:
@@ -171,6 +193,23 @@ async def startup_event():
171
  except Exception as e:
172
  # Log but continue; agentic_workflow has fallback behavior
173
  print(f"Worker: initialize_database failed: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  else:
175
  print("Worker: no database available (no env DB, no profiles, no demo bundle)")
176
  # Optional Groq Vision health check in cloud mode
@@ -370,7 +409,8 @@ async def upload_image(file: UploadFile = File(...)):
370
 
371
  @app.get("/schemas")
372
  async def schemas_list():
373
- return {"profiles": profile_registry.list(), "active_id": profile_registry.active_id}
 
374
 
375
 
376
  @app.post("/schemas/add")
@@ -393,7 +433,7 @@ async def schemas_add_json(req: AddSchemaJsonReq):
393
  except Exception as e:
394
  raise HTTPException(status_code=400, detail=f"Profile saved, but DB init failed: {e}")
395
  # Return full schema digest preview
396
- return {"profile": entry, "schema": agent.ACTIVE_SCHEMA_PROFILE.summarize() if agent else None}
397
 
398
 
399
  @app.post("/schemas/add-file")
@@ -462,7 +502,7 @@ async def schemas_add_file(file: UploadFile = File(...), name: Optional[str] = F
462
  await agent.initialize_database(uri=db_url, schema_notes=notes)
463
  except Exception as e:
464
  raise HTTPException(status_code=400, detail=f"Profile saved, but DB init failed: {e}")
465
- return {"profile": entry, "schema": agent.ACTIVE_SCHEMA_PROFILE.summarize() if agent else None}
466
 
467
 
468
  @app.post("/schemas/switch/{profile_id}")
@@ -484,7 +524,7 @@ async def schemas_switch(profile_id: str):
484
  await agent.initialize_database(uri=entry["db_url"], schema_notes=entry.get("notes"))
485
  except Exception as e:
486
  raise HTTPException(status_code=400, detail=f"Switch failed: {e}")
487
- return {"profile": entry, "schema": agent.ACTIVE_SCHEMA_PROFILE.summarize()}
488
 
489
 
490
  class SetSchemaNotesReq(BaseModel):
 
18
  # Schema profile registry (dynamic multi-DB support)
19
  # ---------------------------------------------------------------------------
20
  try:
21
+ from .schema_profile import ProfileRegistry, _redact_db_url
22
  except Exception:
23
  import Agent.schema_profile as _sp
24
  ProfileRegistry = _sp.ProfileRegistry
25
+ _redact_db_url = _sp._redact_db_url
26
 
27
  SCHEMAS_DIR = os.path.join("uploads", "schemas")
28
  PROFILE_STORE_PATH = os.path.join("chat_store", "schema_profiles.json")
29
  profile_registry = ProfileRegistry(PROFILE_STORE_PATH)
30
 
31
+
32
+ def _safe_profile(entry):
33
+ """Copy of a registry entry safe for public API responses (password masked)."""
34
+ if not isinstance(entry, dict):
35
+ return entry
36
+ safe = dict(entry)
37
+ safe["db_url"] = _redact_db_url(safe.get("db_url"))
38
+ return safe
39
+
40
  SUPPORTED_DB_SUFFIXES = {".sqlite", ".db", ".sqlite3", ".csv"}
41
 
42
 
 
129
  # ------------------------------------------------------------------
130
  db_url = os.environ.get("DB_CONNECTION_URL")
131
  active = profile_registry.active()
132
+ # Boot priority: 1) the user's last ACTIVATED profile (persisted across
133
+ # restarts; never the auto-registered demo placeholder), 2) the env
134
+ # DB_CONNECTION_URL, 3) the bundled demo file. Previously the env secret
135
+ # ALWAYS won, so every restart silently yanked the engine back to the
136
+ # owner's default database even when the registry said the user was
137
+ # working in (e.g.) their car database — engine and registry disagreed
138
+ # and queries ran against the wrong database.
139
+ _active_kind = (active or {}).get("kind")
140
+ target_uri = (
141
+ (active or {}).get("db_url")
142
+ if active and _active_kind != "demo"
143
+ else None
144
+ ) or db_url or demo_db_url
145
 
146
  if target_uri:
147
  try:
 
193
  except Exception as e:
194
  # Log but continue; agentic_workflow has fallback behavior
195
  print(f"Worker: initialize_database failed: {e}")
196
+ # If the persisted profile's DB became unreachable (rotated
197
+ # credentials, deleted file), retry once with the env DB so the
198
+ # worker still boots with a usable database.
199
+ if db_url and target_uri != db_url:
200
+ try:
201
+ print("[WORKER] Falling back to DB_CONNECTION_URL after failed profile boot")
202
+ await agent.initialize_database(uri=db_url)
203
+ _env_match = next(
204
+ (p for p in profile_registry.list()
205
+ if ((p.get("db_url") or "").replace("\\", "/") == db_url.replace("\\", "/"))),
206
+ None,
207
+ )
208
+ if _env_match and profile_registry.active_id != _env_match["id"]:
209
+ profile_registry.switch(_env_match["id"])
210
+ print(f"[WORKER] Active profile switched to '{_env_match['name']}' (env fallback)")
211
+ except Exception as e2:
212
+ print(f"Worker: env fallback failed: {e2}")
213
  else:
214
  print("Worker: no database available (no env DB, no profiles, no demo bundle)")
215
  # Optional Groq Vision health check in cloud mode
 
409
 
410
  @app.get("/schemas")
411
  async def schemas_list():
412
+ return {"profiles": [_safe_profile(p) for p in profile_registry.list()],
413
+ "active_id": profile_registry.active_id}
414
 
415
 
416
  @app.post("/schemas/add")
 
433
  except Exception as e:
434
  raise HTTPException(status_code=400, detail=f"Profile saved, but DB init failed: {e}")
435
  # Return full schema digest preview
436
+ return {"profile": _safe_profile(entry), "schema": agent.ACTIVE_SCHEMA_PROFILE.summarize() if agent else None}
437
 
438
 
439
  @app.post("/schemas/add-file")
 
502
  await agent.initialize_database(uri=db_url, schema_notes=notes)
503
  except Exception as e:
504
  raise HTTPException(status_code=400, detail=f"Profile saved, but DB init failed: {e}")
505
+ return {"profile": _safe_profile(entry), "schema": agent.ACTIVE_SCHEMA_PROFILE.summarize() if agent else None}
506
 
507
 
508
  @app.post("/schemas/switch/{profile_id}")
 
524
  await agent.initialize_database(uri=entry["db_url"], schema_notes=entry.get("notes"))
525
  except Exception as e:
526
  raise HTTPException(status_code=400, detail=f"Switch failed: {e}")
527
+ return {"profile": _safe_profile(entry), "schema": agent.ACTIVE_SCHEMA_PROFILE.summarize()}
528
 
529
 
530
  class SetSchemaNotesReq(BaseModel):