-
Notifications
You must be signed in to change notification settings - Fork 0
feat(v0.7.2): data-flow correctness — fix the 27K→35 dashboard gap #175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
|
|
||
| Requires: pip install gradata openai | ||
| """ | ||
|
|
||
| from pathlib import Path | ||
|
|
||
| from openai import OpenAI | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1231,11 +1231,15 @@ def _cloud_sync_session( | |||||||||||||||||||||||||||
| """Best-effort cloud sync at session end. Never raises, never blocks.""" | ||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||
| import hashlib | ||||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||||
| from pathlib import Path | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| # 1. Resolve cloud credentials: ~/.gradata/config.toml or env var | ||||||||||||||||||||||||||||
| api_key = os.environ.get("GRADATA_API_KEY", "") | ||||||||||||||||||||||||||||
| # 1. Resolve cloud credentials: per-brain cloud-config.json, keyfile, | ||||||||||||||||||||||||||||
| # legacy ~/.gradata/config.toml, or env var. | ||||||||||||||||||||||||||||
| from gradata.cloud import _credentials as _cloud_creds | ||||||||||||||||||||||||||||
| from gradata.cloud.sync import load_config as _load_cloud_config | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| brain_cloud_cfg = _load_cloud_config(brain.dir) | ||||||||||||||||||||||||||||
| api_key = _cloud_creds.resolve_credential(fallback=brain_cloud_cfg.token) | ||||||||||||||||||||||||||||
| api_url = "" | ||||||||||||||||||||||||||||
| brain_id_from_config = "" | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
@@ -1249,6 +1253,7 @@ def _cloud_sync_session( | |||||||||||||||||||||||||||
| except Exception as e: | ||||||||||||||||||||||||||||
| _log.debug("cloud config parse failed: %s", e) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| api_url = _cloud_creds.resolve_endpoint(api_url, fallback=brain_cloud_cfg.api_base) | ||||||||||||||||||||||||||||
| if not api_key: | ||||||||||||||||||||||||||||
| return # No cloud credentials — nothing to sync | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
@@ -1337,17 +1342,15 @@ def _cloud_sync_session( | |||||||||||||||||||||||||||
| sync_client.sync_metrics(payload) | ||||||||||||||||||||||||||||
| _log.debug("Cloud telemetry synced for session %d", session) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| # Finding 11: respect sync_mode — default is metrics_only. | ||||||||||||||||||||||||||||
| # Only sync full events/corrections if explicitly opted in via config. | ||||||||||||||||||||||||||||
| sync_mode = "metrics_only" | ||||||||||||||||||||||||||||
| sync_mode = getattr(brain_cloud_cfg, "sync_mode", "full") or "full" | ||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||
| cfg = _parse_toml_cloud(config_path) | ||||||||||||||||||||||||||||
| sync_mode = cfg.get("sync_mode", "metrics_only") | ||||||||||||||||||||||||||||
| sync_mode = cfg.get("sync_mode", sync_mode) | ||||||||||||||||||||||||||||
|
Comment on lines
+1345
to
+1348
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not let legacy TOML override the per-brain These lines can undo the Suggested fix- sync_mode = getattr(brain_cloud_cfg, "sync_mode", "full") or "full"
- try:
- cfg = _parse_toml_cloud(config_path)
- sync_mode = cfg.get("sync_mode", sync_mode)
- except Exception:
- pass
+ sync_mode = str(getattr(brain_cloud_cfg, "sync_mode", "") or "").strip().lower()
+ if not sync_mode and config_path.is_file():
+ try:
+ cfg = _parse_toml_cloud(config_path)
+ sync_mode = str(cfg.get("sync_mode", "") or "").strip().lower()
+ except Exception:
+ pass
+ sync_mode = sync_mode or "full"📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||
| except Exception: | ||||||||||||||||||||||||||||
| pass | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if sync_mode == "full": | ||||||||||||||||||||||||||||
| # 4. Sync events/corrections via the full cloud client (opt-in only) | ||||||||||||||||||||||||||||
| # 4. Sync events/corrections via the full cloud client. | ||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||
| from gradata.cloud.client import CloudClient | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
@@ -1361,9 +1364,14 @@ def _cloud_sync_session( | |||||||||||||||||||||||||||
| _log.debug("Cloud event sync completed for session %d", session) | ||||||||||||||||||||||||||||
| except Exception as e: | ||||||||||||||||||||||||||||
| _log.debug("Cloud event sync failed (non-fatal): %s", e) | ||||||||||||||||||||||||||||
| elif sync_mode == "metrics_only": | ||||||||||||||||||||||||||||
| _log.warning( | ||||||||||||||||||||||||||||
| "Skipping event/correction sync (sync_mode=metrics_only) — dashboard will " | ||||||||||||||||||||||||||||
| "not show corrections. Run `gradata sync --full` to backfill." | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||
| _log.debug( | ||||||||||||||||||||||||||||
| "Cloud sync_mode=%s — skipping event/correction sync for session %d", | ||||||||||||||||||||||||||||
| _log.warning( | ||||||||||||||||||||||||||||
| "Unknown cloud sync_mode=%s — skipping event/correction sync for session %d", | ||||||||||||||||||||||||||||
| sync_mode, | ||||||||||||||||||||||||||||
| session, | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honor
sync_enabledbefore resolving shared credentials.This auto-sync path now uploads whenever a global keyfile or env credential exists, even if this brain was never cloud-enabled. That can leak data from the wrong brain as soon as
brain_end_session()runs.Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents