Spaces:
Running
Running
Download scripts/probe_openrouter_contracts.py from ifieryarrows/copper-mind: direct link, hf CLI and curl.
- Browser
- Download file 5.85 kB
-
https://huggingface.co/spaces/ifieryarrows/copper-mind/resolve/main/scripts/probe_openrouter_contracts.py
- Command line
-
hf download hf://spaces/ifieryarrows/copper-mind/scripts/probe_openrouter_contracts.py
-
curl -L -o probe_openrouter_contracts.py https://huggingface.co/spaces/ifieryarrows/copper-mind/resolve/main/scripts/probe_openrouter_contracts.py
5.85 kB
| """Live, non-mocked probe for the exact sentiment and commentary contracts.""" | |
| from __future__ import annotations | |
| import argparse | |
| import asyncio | |
| import json | |
| import pathlib | |
| import sys | |
| from types import SimpleNamespace | |
| BACKEND_ROOT = pathlib.Path(__file__).resolve().parents[1] | |
| if str(BACKEND_ROOT) not in sys.path: | |
| sys.path.insert(0, str(BACKEND_ROOT)) | |
| from app import ai_engine, commentary | |
| from app.settings import get_settings | |
| async def run_probe(*, fast: str, reliable: str, commentary_model: str, batch_size: int = 12) -> dict: | |
| runtime = get_settings() | |
| api_keys = runtime.openrouter_api_keys | |
| if not api_keys: | |
| return {"ok": False, "error": "OpenRouter credential is not configured"} | |
| probe_settings = SimpleNamespace( | |
| openrouter_api_key=runtime.openrouter_api_key, | |
| openrouter_api_key_backup=runtime.openrouter_api_key_backup, | |
| openrouter_api_keys=api_keys, | |
| openrouter_max_retries=1, | |
| openrouter_rpm=runtime.openrouter_rpm, | |
| openrouter_timeout_seconds=runtime.openrouter_timeout_seconds, | |
| openrouter_chain_deadline_seconds=runtime.openrouter_chain_deadline_seconds, | |
| openrouter_fallback_models_list=[], | |
| resolved_scoring_fast_model=fast, | |
| resolved_scoring_reliable_model=reliable, | |
| resolved_commentary_model=commentary_model, | |
| ) | |
| original_ai_settings = ai_engine.get_settings | |
| original_commentary_settings = commentary.get_settings | |
| ai_engine.get_settings = lambda: probe_settings | |
| commentary.get_settings = lambda: probe_settings | |
| try: | |
| # Match the worker's 12-article V2 scoring chunk, using synthetic | |
| # scenarios so the probe never depends on mutable market data. | |
| scenarios = [ | |
| ("Copper mine outage", "A temporary outage reduces concentrate shipments."), | |
| ("Refinery restart", "A smelter resumes production after scheduled maintenance."), | |
| ("Grid demand rises", "New grid projects increase near-term copper orders."), | |
| ("Dollar strengthens", "The US dollar rises against major currencies."), | |
| ("Warehouse inventories fall", "Exchange-registered copper stocks decline."), | |
| ("Scrap supply expands", "More secondary copper enters the market."), | |
| ("Housing starts slow", "Construction demand weakens this quarter."), | |
| ("Electronics orders improve", "Manufacturers report stronger copper demand."), | |
| ("Port disruption ends", "Concentrate exports resume after a short delay."), | |
| ("Oil price changes", "Crude oil moves with no stated copper link."), | |
| ("New mine commissioning", "Additional copper capacity begins operating."), | |
| ("Mixed industrial data", "Orders rise in one region and fall in another."), | |
| ] | |
| articles = [ | |
| {"id": index + 1, "title": f"Synthetic contract probe: {title}", "description": description} | |
| for index, (title, description) in enumerate(scenarios[:max(1, min(batch_size, 12))]) | |
| ] | |
| scoring = {} | |
| for role, model, repair in ( | |
| ("fast", fast, reliable), | |
| ("reliable", reliable, fast), | |
| ): | |
| valid, failed, metrics, rate_limited = await ai_engine._score_subset_with_model_v2( | |
| settings=probe_settings, | |
| model_name=model, | |
| repair_model_name=repair, | |
| articles=articles, | |
| horizon_days=5, | |
| ) | |
| result = valid.get(1) | |
| scoring[role] = { | |
| "requested_model": model, | |
| "actual_model": result.get("llm_model") if result else None, | |
| "item_count": len(articles), | |
| "valid_count": len(valid), | |
| "ok_without_repair": bool(len(valid) == len(articles) and not failed and metrics.get("repair_success_count", 0) == 0), | |
| "failure_category": metrics.get("failure_category"), | |
| "rate_limited": bool(rate_limited), | |
| } | |
| commentary_result = await commentary._generate_commentary_and_stance( | |
| current_price=6.6, | |
| predicted_price=6.62, | |
| predicted_return=0.003, | |
| sentiment_index=0.2, | |
| sentiment_label="Bullish", | |
| top_influencers=[{"feature": "sentiment__index", "importance": 0.2}], | |
| news_count=8, | |
| ) | |
| commentary_probe = { | |
| "requested_model": commentary_model, | |
| "actual_model": commentary_result.model_name, | |
| "generation_mode": commentary_result.generation_mode, | |
| "fallback_reason": commentary_result.fallback_reason, | |
| "ok_without_repair": commentary_result.generation_mode == "llm", | |
| } | |
| ok = all(item["ok_without_repair"] for item in scoring.values()) and commentary_probe["ok_without_repair"] | |
| return {"ok": ok, "scoring": scoring, "commentary": commentary_probe} | |
| finally: | |
| ai_engine.get_settings = original_ai_settings | |
| commentary.get_settings = original_commentary_settings | |
| def main() -> int: | |
| parser = argparse.ArgumentParser(description="Probe exact OpenRouter production contracts") | |
| parser.add_argument("--fast", default="nvidia/nemotron-3.5-super-vl:free") | |
| parser.add_argument("--reliable", default="google/gemma-4-31b-it:free") | |
| parser.add_argument("--commentary", default="google/gemma-4-31b-it:free") | |
| parser.add_argument("--batch-size", type=int, default=12, help="Synthetic scoring items, up to the worker's 12-item chunk") | |
| args = parser.parse_args() | |
| result = asyncio.run(run_probe(fast=args.fast, reliable=args.reliable, commentary_model=args.commentary, batch_size=args.batch_size)) | |
| print(json.dumps(result, indent=2)) | |
| return 0 if result.get("ok") else 1 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |