openrunner-sdk 2.17.0__tar.gz → 2.17.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/PKG-INFO +1 -1
  2. openrunner_sdk-2.17.2/openrunner/CLAUDE.md +15 -0
  3. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/__init__.py +1 -1
  4. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/install_commands.py +27 -0
  5. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/mcp_server.py +73 -0
  6. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/pyproject.toml +1 -1
  7. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/.gitignore +0 -0
  8. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/=6.0 +0 -0
  9. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/=8.1 +0 -0
  10. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/README.md +0 -0
  11. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/api_client.py +0 -0
  12. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/artifact.py +0 -0
  13. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/buffer.py +0 -0
  14. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/cache.py +0 -0
  15. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/cli.py +0 -0
  16. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/config.py +0 -0
  17. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/cost.py +0 -0
  18. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/dataset.py +0 -0
  19. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/environment.py +0 -0
  20. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/evaluation.py +0 -0
  21. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/feedback.py +0 -0
  22. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/git_info.py +0 -0
  23. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/guardrails.py +0 -0
  24. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/__init__.py +0 -0
  25. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/accelerate.py +0 -0
  26. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/anthropic_tracer.py +0 -0
  27. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/catboost.py +0 -0
  28. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/diffusers.py +0 -0
  29. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/fastai.py +0 -0
  30. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/forced_alignment.py +0 -0
  31. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/gladia.py +0 -0
  32. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/gymnasium.py +0 -0
  33. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/huggingface.py +0 -0
  34. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/hydra.py +0 -0
  35. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/ignite.py +0 -0
  36. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/jax.py +0 -0
  37. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/keras.py +0 -0
  38. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/langchain.py +0 -0
  39. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/lightgbm.py +0 -0
  40. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/lightning.py +0 -0
  41. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/llamaindex.py +0 -0
  42. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/openai_finetune.py +0 -0
  43. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/openai_tracer.py +0 -0
  44. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/optuna.py +0 -0
  45. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/pytorch.py +0 -0
  46. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/sb3.py +0 -0
  47. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/sklearn.py +0 -0
  48. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/tensorflow.py +0 -0
  49. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/trl.py +0 -0
  50. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/tts.py +0 -0
  51. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/ultralytics.py +0 -0
  52. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/voice_agent.py +0 -0
  53. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/whisper.py +0 -0
  54. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/integration/xgboost.py +0 -0
  55. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/launch.py +0 -0
  56. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/media.py +0 -0
  57. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/migrate.py +0 -0
  58. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/model.py +0 -0
  59. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/offline.py +0 -0
  60. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/pii.py +0 -0
  61. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/plot.py +0 -0
  62. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/prompt.py +0 -0
  63. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/query_api.py +0 -0
  64. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/redact.py +0 -0
  65. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/run.py +0 -0
  66. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/scorers.py +0 -0
  67. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/sender.py +0 -0
  68. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/session.py +0 -0
  69. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/settings.py +0 -0
  70. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/summary.py +0 -0
  71. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/sweep.py +0 -0
  72. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/system_metrics.py +0 -0
  73. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/tensorboard.py +0 -0
  74. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/trace.py +0 -0
  75. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/transcript_formatter.py +0 -0
  76. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/wal.py +0 -0
  77. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/wandb_compat/__init__.py +0 -0
  78. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/wandb_compat/_shim.py +0 -0
  79. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/openrunner/wer.py +0 -0
  80. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/__init__.py +0 -0
  81. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/conftest.py +0 -0
  82. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_alert.py +0 -0
  83. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_aliases.py +0 -0
  84. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_api_client.py +0 -0
  85. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_artifact.py +0 -0
  86. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_buffer.py +0 -0
  87. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_cache.py +0 -0
  88. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_class_scorers.py +0 -0
  89. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_cli.py +0 -0
  90. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_config.py +0 -0
  91. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_evaluation.py +0 -0
  92. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_finish.py +0 -0
  93. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_git_info.py +0 -0
  94. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_init.py +0 -0
  95. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_integration_fastai.py +0 -0
  96. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_integration_huggingface.py +0 -0
  97. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_integration_keras.py +0 -0
  98. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_integration_langchain.py +0 -0
  99. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_integration_lightning.py +0 -0
  100. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_integration_pytorch.py +0 -0
  101. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_integration_sklearn.py +0 -0
  102. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_integration_xgboost.py +0 -0
  103. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_launch.py +0 -0
  104. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_log.py +0 -0
  105. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_log_code.py +0 -0
  106. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_media.py +0 -0
  107. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_migrate.py +0 -0
  108. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_offline.py +0 -0
  109. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_offline_sync.py +0 -0
  110. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_pii.py +0 -0
  111. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_plot.py +0 -0
  112. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_query_api.py +0 -0
  113. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_resume.py +0 -0
  114. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_sdk_features.py +0 -0
  115. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_sender.py +0 -0
  116. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_summary.py +0 -0
  117. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_sweep.py +0 -0
  118. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_system_metrics.py +0 -0
  119. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_trace.py +0 -0
  120. {openrunner_sdk-2.17.0 → openrunner_sdk-2.17.2}/tests/test_wandb_compat.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openrunner-sdk
3
- Version: 2.17.0
3
+ Version: 2.17.2
4
4
  Summary: OpenRunner SDK - W&B-compatible ML experiment tracking client
5
5
  Project-URL: Homepage, https://github.com/jqueguiner/openrunner
6
6
  Project-URL: Repository, https://github.com/jqueguiner/openrunner
@@ -0,0 +1,15 @@
1
+ # OpenRunner MCP Integration
2
+
3
+ When the user asks about training metrics, loss charts, run data, or experiment results:
4
+ - Use `mcp__openrunner__openrunner_watch_run` to show ASCII sparkline charts
5
+ - Use `mcp__openrunner__openrunner_get_run_metrics` for raw metrics
6
+ - Use `mcp__openrunner__openrunner_list_runs` to find runs
7
+ - Use `mcp__openrunner__openrunner_search_sessions` to search AI session history
8
+
9
+ Do NOT parse log files or grep for metrics when OpenRunner MCP tools are available.
10
+
11
+ When the user asks about papers, research, or sessions:
12
+ - Use `mcp__openrunner__openrunner_search_papers` for paper content
13
+ - Use `mcp__openrunner__openrunner_search_research` for research plans
14
+ - Use `mcp__openrunner__openrunner_search_sessions` for AI session history
15
+ - Use `mcp__openrunner__openrunner_update_paper` to modify paper sections
@@ -120,7 +120,7 @@ launch.from_run = _launch_from_run # type: ignore[attr-defined]
120
120
  # openrunner.trace.patch_openai() syntax
121
121
  trace.patch_openai = _patch_openai # type: ignore[attr-defined]
122
122
 
123
- __version__ = "2.17.0"
123
+ __version__ = "2.17.2"
124
124
 
125
125
  logger = logging.getLogger("openrunner")
126
126
 
@@ -543,6 +543,33 @@ def install_claude_code() -> list[str]:
543
543
  path.write_text(template.format(prefix="openrunner:"))
544
544
  files.append(str(path))
545
545
 
546
+ # Install CLAUDE.md with MCP usage instructions
547
+ claude_md = Path.home() / ".claude" / "CLAUDE.md"
548
+ mcp_instructions = """# OpenRunner MCP Integration
549
+
550
+ When the user asks about training metrics, loss charts, run data, or experiment results:
551
+ - Use `mcp__openrunner__openrunner_watch_run` to show ASCII sparkline charts
552
+ - Use `mcp__openrunner__openrunner_get_run_metrics` for raw metrics
553
+ - Use `mcp__openrunner__openrunner_list_runs` to find runs
554
+ - Use `mcp__openrunner__openrunner_search_sessions` to search AI session history
555
+
556
+ Do NOT parse log files or grep for metrics when OpenRunner MCP tools are available.
557
+
558
+ When the user asks about papers, research, or sessions:
559
+ - Use `mcp__openrunner__openrunner_search_papers` for paper content
560
+ - Use `mcp__openrunner__openrunner_search_research` for research plans
561
+ - Use `mcp__openrunner__openrunner_search_sessions` for AI session history
562
+ - Use `mcp__openrunner__openrunner_update_paper` to modify paper sections
563
+ """
564
+ if claude_md.exists():
565
+ content = claude_md.read_text()
566
+ if "openrunner" not in content.lower():
567
+ claude_md.write_text(content + "\n" + mcp_instructions)
568
+ files.append(str(claude_md))
569
+ else:
570
+ claude_md.write_text(mcp_instructions)
571
+ files.append(str(claude_md))
572
+
546
573
  return files
547
574
 
548
575
 
@@ -292,6 +292,19 @@ def create_server():
292
292
  "required": ["query"],
293
293
  },
294
294
  ),
295
+ Tool(
296
+ name="openrunner_watch_run",
297
+ description="Get latest metrics for a run and render as ASCII chart. Use to monitor training progress.",
298
+ inputSchema={
299
+ "type": "object",
300
+ "properties": {
301
+ "run_id": {"type": "string", "description": "Run ID to watch"},
302
+ "metric": {"type": "string", "description": "Metric key (default: train/loss)", "default": "train/loss"},
303
+ "width": {"type": "integer", "description": "Chart width in chars (default: 60)", "default": 60},
304
+ },
305
+ "required": ["run_id"],
306
+ },
307
+ ),
295
308
  Tool(
296
309
  name="openrunner_update_paper",
297
310
  description="Update a paper's title, abstract, or section content (LaTeX).",
@@ -352,6 +365,8 @@ def create_server():
352
365
  result = await _tool_search_papers(arguments)
353
366
  elif name == "openrunner_update_paper":
354
367
  result = await _tool_update_paper(arguments)
368
+ elif name == "openrunner_watch_run":
369
+ result = await _tool_watch_run(arguments)
355
370
  elif name == "openrunner_search_research":
356
371
  result = await _tool_search_research(arguments)
357
372
  else:
@@ -735,6 +750,64 @@ async def _tool_search_papers(args: dict) -> str:
735
750
  return f"Error: {e}"
736
751
 
737
752
 
753
+ async def _tool_watch_run(args: dict) -> str:
754
+ """Get metrics for a run and render ASCII sparkline chart."""
755
+ run_id = args["run_id"]
756
+ metric_key = args.get("metric", "train/loss")
757
+ width = args.get("width", 60)
758
+
759
+ try:
760
+ data = await _api_get(f"/runs/{run_id}/metrics", params={"keys": metric_key})
761
+ points = data.get("metrics", {}).get(metric_key, [])
762
+ if not points:
763
+ # Try without namespace
764
+ all_metrics = data.get("metrics", {})
765
+ if all_metrics:
766
+ # Show available keys
767
+ keys = list(all_metrics.keys())
768
+ return f"No '{metric_key}' data. Available: {', '.join(keys[:20])}"
769
+ return f"No metrics yet for run {run_id}. Training may still be starting."
770
+
771
+ # Extract values
772
+ values = [p.get("value", p) if isinstance(p, dict) else p for p in points]
773
+ steps = [p.get("step", i) if isinstance(p, dict) else i for i, p in enumerate(points)]
774
+
775
+ if not values:
776
+ return "No numeric values found."
777
+
778
+ # ASCII chart
779
+ min_v = min(values)
780
+ max_v = max(values)
781
+ range_v = max_v - min_v or 1
782
+ height = 10
783
+ chart_width = min(width, len(values))
784
+
785
+ # Sample if too many points
786
+ if len(values) > chart_width:
787
+ step_size = len(values) / chart_width
788
+ sampled = [values[int(i * step_size)] for i in range(chart_width)]
789
+ else:
790
+ sampled = values
791
+
792
+ # Build chart
793
+ bars = "▁▂▃▄▅▆▇█"
794
+ sparkline = ""
795
+ for v in sampled:
796
+ idx = int((v - min_v) / range_v * (len(bars) - 1))
797
+ sparkline += bars[idx]
798
+
799
+ lines = []
800
+ lines.append(f"📊 {metric_key} — run {run_id}")
801
+ lines.append(f" Steps: {steps[0]}→{steps[-1]} ({len(values)} points)")
802
+ lines.append(f" Range: {min_v:.4f} → {max_v:.4f} (latest: {values[-1]:.4f})")
803
+ lines.append(f" {sparkline}")
804
+ lines.append(f" {'↑' if values[-1] > values[0] else '↓'} {'rising' if values[-1] > values[0] else 'falling'} ({((values[-1] - values[0]) / (values[0] or 1)) * 100:.1f}%)")
805
+
806
+ return "\n".join(lines)
807
+ except Exception as e:
808
+ return f"Error fetching metrics: {e}"
809
+
810
+
738
811
  async def _tool_update_paper(args: dict) -> str:
739
812
  """Update a paper's title, abstract, or section content."""
740
813
  paper_id = args["paper_id"]
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "openrunner-sdk"
3
- version = "2.17.0"
3
+ version = "2.17.2"
4
4
  description = "OpenRunner SDK - W&B-compatible ML experiment tracking client"
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}
File without changes
File without changes