AlexWortega commited on
Commit
b4118f1
·
verified ·
1 Parent(s): a91dde1

feedback: synchronous dataset upload (ZeroGPU-safe)

Browse files
Files changed (1) hide show
  1. app.py +29 -26
app.py CHANGED
@@ -48,40 +48,43 @@ from huggingface_hub import hf_hub_download
48
  from llama_cpp import Llama
49
 
50
  # ---- feedback logging (JSONL, synced to a private HF dataset) ----
 
 
 
 
 
51
  FEEDBACK_REPO = os.environ.get("FEEDBACK_REPO", "AlexWortega/my-pi-agent-feedback")
52
  _FB_DIR = Path("feedback")
53
  _FB_DIR.mkdir(exist_ok=True)
54
  _FB_FILE = _FB_DIR / f"log_{uuid.uuid4().hex}.jsonl"
55
- _scheduler = None
56
- try:
57
- if os.environ.get("HF_TOKEN"):
58
- from huggingface_hub import CommitScheduler
59
-
60
- _scheduler = CommitScheduler(
61
- repo_id=FEEDBACK_REPO,
62
- repo_type="dataset",
63
- folder_path=_FB_DIR,
64
- path_in_repo="data",
65
- every=5,
66
- token=os.environ["HF_TOKEN"],
67
- )
68
- print("feedback CommitScheduler -> ", FEEDBACK_REPO, flush=True)
69
- except Exception as e: # noqa: BLE001
70
- print("feedback scheduler disabled:", repr(e)[:160], flush=True)
71
 
72
 
73
  def _log(record):
74
- record = {"ts": datetime.datetime.utcnow().isoformat() + "Z", **record}
 
 
 
75
  try:
76
- if _scheduler is not None:
77
- with _scheduler.lock:
78
- with _FB_FILE.open("a", encoding="utf-8") as f:
79
- f.write(json.dumps(record, ensure_ascii=False) + "\n")
80
- else:
81
- with _FB_FILE.open("a", encoding="utf-8") as f:
82
- f.write(json.dumps(record, ensure_ascii=False) + "\n")
83
  except Exception as e: # noqa: BLE001
84
- print("log failed:", repr(e)[:120], flush=True)
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  # ---- model (GGUF pulled from the Hub at startup, runs on ZeroGPU) ----
87
  GGUF_REPO = os.environ.get("GGUF_REPO", "AlexWortega/qwen35-4b-soyuz-merged-gguf")
@@ -243,9 +246,9 @@ def respond(message, history, system_prompt, temperature, max_tokens, meta):
243
  "code": doc,
244
  "reaction": None,
245
  }
246
- _log(record)
247
  meta = meta + [record]
248
  yield history, "", raw, (thinking or _NO_REASONING), doc, _iframe(doc), meta
 
249
 
250
 
251
  def on_like(meta, evt: gr.LikeData):
 
48
  from llama_cpp import Llama
49
 
50
  # ---- feedback logging (JSONL, synced to a private HF dataset) ----
51
+ # NB: huggingface_hub.CommitScheduler's background thread breaks under ZeroGPU's
52
+ # process forking ("Invalid file descriptor: -1"), so we append locally and push
53
+ # the file synchronously from the main process instead.
54
+ from huggingface_hub import HfApi
55
+
56
  FEEDBACK_REPO = os.environ.get("FEEDBACK_REPO", "AlexWortega/my-pi-agent-feedback")
57
  _FB_DIR = Path("feedback")
58
  _FB_DIR.mkdir(exist_ok=True)
59
  _FB_FILE = _FB_DIR / f"log_{uuid.uuid4().hex}.jsonl"
60
+ _FB_PATH_IN_REPO = f"data/{_FB_FILE.name}"
61
+ _HF_TOKEN = os.environ.get("HF_TOKEN")
62
+ _api = HfApi(token=_HF_TOKEN) if _HF_TOKEN else None
63
+ print("feedback ->", FEEDBACK_REPO if _api else "(local only, no HF_TOKEN)", flush=True)
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
 
66
  def _log(record):
67
+ record = {
68
+ "ts": datetime.datetime.now(datetime.timezone.utc).isoformat(),
69
+ **record,
70
+ }
71
  try:
72
+ with _FB_FILE.open("a", encoding="utf-8") as f:
73
+ f.write(json.dumps(record, ensure_ascii=False) + "\n")
 
 
 
 
 
74
  except Exception as e: # noqa: BLE001
75
+ print("local log failed:", repr(e)[:120], flush=True)
76
+ return
77
+ if _api is not None:
78
+ try:
79
+ _api.upload_file(
80
+ path_or_fileobj=str(_FB_FILE),
81
+ path_in_repo=_FB_PATH_IN_REPO,
82
+ repo_id=FEEDBACK_REPO,
83
+ repo_type="dataset",
84
+ commit_message="feedback log",
85
+ )
86
+ except Exception as e: # noqa: BLE001
87
+ print("dataset upload failed:", repr(e)[:160], flush=True)
88
 
89
  # ---- model (GGUF pulled from the Hub at startup, runs on ZeroGPU) ----
90
  GGUF_REPO = os.environ.get("GGUF_REPO", "AlexWortega/qwen35-4b-soyuz-merged-gguf")
 
246
  "code": doc,
247
  "reaction": None,
248
  }
 
249
  meta = meta + [record]
250
  yield history, "", raw, (thinking or _NO_REASONING), doc, _iframe(doc), meta
251
+ _log(record) # after yield: upload doesn't block the visible response
252
 
253
 
254
  def on_like(meta, evt: gr.LikeData):