feat: optional Supabase observatory logging for token savings - #16
feat: optional Supabase observatory logging for token savings#16MAIAppraiser wants to merge 3 commits into
Conversation
…ation results Co-Authored-By: Oz <oz-agent@warp.dev>
- Add observatory module with ureq REST client (LOWFAT_SUPABASE_* or SUPABASE_* envs) - Log savings to eng_technologies + eng_evaluations after local DB writes - Surface "🌐 observatory: on" in status when enabled - Best-effort, non-blocking, thread-spawned (sync under DEBUG) - Privacy: only aggregates + command/subcommand; no raw content - Graceful degradation when disabled or unreachable Co-Authored-By: Oz <oz-agent@warp.dev>
Co-Authored-By: Oz <oz-agent@warp.dev>
| if !enabled() { | ||
| return; | ||
| } | ||
| let dir = data_dir.to_path_buf(); |
There was a problem hiding this comment.
This could be a bug since main.rs calls process::exit right after run() returns, killing this thread before the POST finishes.
Only the LOWFAT_OBSERVATORY_DEBUG=1 sync path actually works.
Might fix with: return the JoinHandle and join it after printing output ?
| static ENABLED: std::sync::OnceLock<bool> = std::sync::OnceLock::new(); | ||
|
|
||
| /// Returns true if observatory credentials are configured (checked once). | ||
| pub fn enabled() -> bool { | ||
| *ENABLED.get_or_init(|| resolve_url_key().is_some()) | ||
| } | ||
|
|
||
| fn resolve_url_key() -> Option<(String, String)> { | ||
| let url = std::env::var("LOWFAT_SUPABASE_URL") | ||
| .or_else(|_| std::env::var("SUPABASE_URL")) | ||
| .ok()?; | ||
| let key = std::env::var("LOWFAT_SUPABASE_KEY") |
There was a problem hiding this comment.
Many people have SUPABASE_URL/SUPABASE_SERVICE_ROLE_KEY exported for an unrelated app — this fallback could silently writes rows into that project's DB.
Should better to always have LOWFAT_-prefixed.
| eprintln!("[lowfat] observatory: posting to {}/rest/v1/eng_evaluations (tech ensure first)", url.trim_end_matches('/')); | ||
| } | ||
| let tech_id = ensure_lowfat_technology(&url, &key, data_dir)?; | ||
|
|
There was a problem hiding this comment.
One eng_evaluations row per invocation gets noisy fast in agent sessions. Consider logging only when reduced, or batching.
| .and_then(|v| v.get("id")) | ||
| .and_then(|v| v.as_str()) | ||
| .ok_or("failed to resolve lowfat technology id")? | ||
| .to_string(); | ||
|
|
||
| let _ = std::fs::write(&cache_path, &id); | ||
| Ok(id) |
There was a problem hiding this comment.
This test asserts nothing. Test resolve_url_key() directly or drop it (asserting enabled() would be flaky — OnceLock + parallel tests).
| | `find` | 535 | -0% | -58% | -66% | | ||
|
|
||
| Honest read: lowfat compresses git harder; rtk edges out `find`; `ls` is close. | ||
| | Honest read: lowfat compresses git harder; rtk edges out `find`; `ls` is close. |
There was a problem hiding this comment.
This would turn line into a broken table row.
feat: optional Supabase observatory logging for token savings
Verification:
Co-Authored-By: Oz oz-agent@warp.dev