openrunner-sdk 2.8.0__tar.gz → 2.9.0__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 (118) hide show
  1. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/PKG-INFO +1 -1
  2. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/__init__.py +1 -1
  3. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/session.py +77 -55
  4. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/pyproject.toml +1 -1
  5. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/.gitignore +0 -0
  6. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/=6.0 +0 -0
  7. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/=8.1 +0 -0
  8. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/README.md +0 -0
  9. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/api_client.py +0 -0
  10. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/artifact.py +0 -0
  11. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/buffer.py +0 -0
  12. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/cache.py +0 -0
  13. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/cli.py +0 -0
  14. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/config.py +0 -0
  15. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/cost.py +0 -0
  16. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/dataset.py +0 -0
  17. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/environment.py +0 -0
  18. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/evaluation.py +0 -0
  19. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/feedback.py +0 -0
  20. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/git_info.py +0 -0
  21. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/guardrails.py +0 -0
  22. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/install_commands.py +0 -0
  23. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/__init__.py +0 -0
  24. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/accelerate.py +0 -0
  25. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/anthropic_tracer.py +0 -0
  26. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/catboost.py +0 -0
  27. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/diffusers.py +0 -0
  28. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/fastai.py +0 -0
  29. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/forced_alignment.py +0 -0
  30. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/gladia.py +0 -0
  31. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/gymnasium.py +0 -0
  32. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/huggingface.py +0 -0
  33. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/hydra.py +0 -0
  34. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/ignite.py +0 -0
  35. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/jax.py +0 -0
  36. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/keras.py +0 -0
  37. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/langchain.py +0 -0
  38. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/lightgbm.py +0 -0
  39. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/lightning.py +0 -0
  40. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/llamaindex.py +0 -0
  41. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/openai_finetune.py +0 -0
  42. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/openai_tracer.py +0 -0
  43. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/optuna.py +0 -0
  44. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/pytorch.py +0 -0
  45. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/sb3.py +0 -0
  46. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/sklearn.py +0 -0
  47. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/tensorflow.py +0 -0
  48. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/trl.py +0 -0
  49. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/tts.py +0 -0
  50. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/ultralytics.py +0 -0
  51. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/voice_agent.py +0 -0
  52. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/whisper.py +0 -0
  53. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/xgboost.py +0 -0
  54. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/launch.py +0 -0
  55. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/media.py +0 -0
  56. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/migrate.py +0 -0
  57. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/model.py +0 -0
  58. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/offline.py +0 -0
  59. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/pii.py +0 -0
  60. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/plot.py +0 -0
  61. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/prompt.py +0 -0
  62. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/query_api.py +0 -0
  63. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/redact.py +0 -0
  64. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/run.py +0 -0
  65. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/scorers.py +0 -0
  66. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/sender.py +0 -0
  67. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/settings.py +0 -0
  68. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/summary.py +0 -0
  69. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/sweep.py +0 -0
  70. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/system_metrics.py +0 -0
  71. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/tensorboard.py +0 -0
  72. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/trace.py +0 -0
  73. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/transcript_formatter.py +0 -0
  74. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/wal.py +0 -0
  75. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/wandb_compat/__init__.py +0 -0
  76. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/wandb_compat/_shim.py +0 -0
  77. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/wer.py +0 -0
  78. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/__init__.py +0 -0
  79. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/conftest.py +0 -0
  80. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_alert.py +0 -0
  81. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_aliases.py +0 -0
  82. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_api_client.py +0 -0
  83. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_artifact.py +0 -0
  84. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_buffer.py +0 -0
  85. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_cache.py +0 -0
  86. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_class_scorers.py +0 -0
  87. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_cli.py +0 -0
  88. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_config.py +0 -0
  89. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_evaluation.py +0 -0
  90. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_finish.py +0 -0
  91. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_git_info.py +0 -0
  92. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_init.py +0 -0
  93. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_fastai.py +0 -0
  94. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_huggingface.py +0 -0
  95. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_keras.py +0 -0
  96. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_langchain.py +0 -0
  97. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_lightning.py +0 -0
  98. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_pytorch.py +0 -0
  99. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_sklearn.py +0 -0
  100. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_xgboost.py +0 -0
  101. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_launch.py +0 -0
  102. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_log.py +0 -0
  103. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_log_code.py +0 -0
  104. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_media.py +0 -0
  105. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_migrate.py +0 -0
  106. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_offline.py +0 -0
  107. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_offline_sync.py +0 -0
  108. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_pii.py +0 -0
  109. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_plot.py +0 -0
  110. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_query_api.py +0 -0
  111. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_resume.py +0 -0
  112. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_sdk_features.py +0 -0
  113. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_sender.py +0 -0
  114. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_summary.py +0 -0
  115. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_sweep.py +0 -0
  116. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_system_metrics.py +0 -0
  117. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_trace.py +0 -0
  118. {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/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.8.0
3
+ Version: 2.9.0
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
@@ -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.8.0"
123
+ __version__ = "2.9.0"
124
124
 
125
125
  logger = logging.getLogger("openrunner")
126
126
 
@@ -506,80 +506,102 @@ def sync_session_to_openrunner(
506
506
 
507
507
  client = APIClient(base_url=base_url, api_key=api_key)
508
508
 
509
- # Create run
509
+ # Resolve project_id from "org/project" format
510
+ project_id = None
511
+ try:
512
+ projects = client.list_projects()
513
+ for p in projects:
514
+ org_name = p.get("org_name", "")
515
+ proj_name = p.get("name", "")
516
+ full_name = f"{org_name}/{proj_name}" if org_name else proj_name
517
+ if full_name == project or proj_name == project:
518
+ project_id = p.get("id")
519
+ break
520
+ except Exception:
521
+ pass
522
+
523
+ if not project_id:
524
+ # Fallback: try creating as a run (backward compat with older servers)
525
+ logger.warning(f"Could not resolve project '{project}', falling back to run creation")
526
+ return _sync_as_run_fallback(client, parsed, project, visibility)
527
+
528
+ # Build AI session data
529
+ source = parsed["source"]
530
+ project_hint = parsed.get("project_hint", "")
531
+ timestamp = parsed.get("ended_at", "")[:16].replace("T", " ")
532
+
533
+ if project_hint:
534
+ short_hint = project_hint.rsplit("/", 1)[-1] if "/" in project_hint else project_hint
535
+ title = f"{source}/{short_hint}/{timestamp}"
536
+ else:
537
+ title = f"{source}/{timestamp}"
538
+
539
+ group_key = f"{source}:{project_hint}" if project_hint else f"{source}:default"
540
+
541
+ session_data = {
542
+ "title": title,
543
+ "source": source,
544
+ "worktree": project_hint,
545
+ "group_key": group_key,
546
+ "summary": parsed.get("summary"),
547
+ "notes": _format_session_notes(parsed),
548
+ "first_message": parsed.get("first_message"),
549
+ "messages": parsed.get("messages"),
550
+ "message_count": parsed.get("message_count", 0),
551
+ "user_message_count": parsed.get("user_message_count", 0),
552
+ "total_tokens": parsed.get("total_tokens", 0),
553
+ "tools_used": parsed.get("tools_used", []),
554
+ "files_touched": parsed.get("files_touched", []),
555
+ "visibility": visibility,
556
+ "tags": [f"source:{source}", f"worktree:{group_key}"],
557
+ "redacted": bool(parsed.get("_redaction")),
558
+ "redaction_mode": parsed.get("_redaction", {}).get("mode") if parsed.get("_redaction") else None,
559
+ "session_file": parsed.get("session_file"),
560
+ "started_at": parsed.get("started_at"),
561
+ "ended_at": parsed.get("ended_at"),
562
+ }
563
+
564
+ # POST to /projects/{project_id}/ai-sessions
565
+ try:
566
+ resp = client._request("post", f"/projects/{project_id}/ai-sessions", json=session_data)
567
+ if resp.status_code in (200, 201):
568
+ result = resp.json()
569
+ client.close()
570
+ return result.get("id")
571
+ else:
572
+ # Server doesn't have AI sessions endpoint yet — fall back to run
573
+ logger.info("AI sessions endpoint not available, falling back to run")
574
+ return _sync_as_run_fallback(client, parsed, project, visibility)
575
+ except Exception as e:
576
+ logger.warning(f"AI session sync failed: {e}")
577
+ client.close()
578
+ return None
579
+
580
+
581
+ def _sync_as_run_fallback(client, parsed: dict, project: str, visibility: str) -> str | None:
582
+ """Fallback: create a run if AI sessions endpoint not available."""
510
583
  source = parsed["source"]
511
584
  timestamp = parsed.get("ended_at", "")[:16].replace("T", " ")
512
585
  project_hint = parsed.get("project_hint", "")
513
586
 
514
- # Build display name: include worktree/project context
515
587
  if project_hint:
516
- # Shorten: /home/ubuntu/openrun → openrun
517
588
  short_hint = project_hint.rsplit("/", 1)[-1] if "/" in project_hint else project_hint
518
589
  run_name = f"{source}/{short_hint}/{timestamp}"
519
590
  else:
520
591
  run_name = f"{source}/{timestamp}"
521
592
 
522
- # Group sessions by source project (worktree)
523
- group_name = f"{source}:{project_hint}" if project_hint else f"{source}:default"
524
-
525
593
  run_data = {
526
594
  "project": project,
527
595
  "display_name": run_name,
528
- "group_name": group_name,
529
- "config": {
530
- "source": source,
531
- "session_file": parsed.get("session_file", ""),
532
- "project_hint": project_hint,
533
- "message_count": parsed.get("message_count", 0),
534
- "user_message_count": parsed.get("user_message_count", 0),
535
- "tools_used": parsed.get("tools_used", []),
536
- "total_tokens": parsed.get("total_tokens", 0),
537
- },
538
- "tags": [f"source:{source}", "ai-session", f"visibility:{visibility}", f"worktree:{group_name}"],
596
+ "group_name": f"{source}:{project_hint}" if project_hint else f"{source}:default",
597
+ "tags": [f"source:{source}", "ai-session"],
539
598
  "notes": _format_session_notes(parsed),
540
599
  "state": "finished",
541
600
  }
542
601
 
543
- # Add redaction metadata if applied
544
- if parsed.get("_redaction"):
545
- run_data["config"]["redacted"] = True
546
- run_data["config"]["redaction_mode"] = parsed["_redaction"]["mode"]
547
- run_data["config"]["entities_redacted"] = parsed["_redaction"]["entities_redacted"]
548
-
549
602
  result = client.create_run(run_data)
550
- if not result:
551
- logger.warning("Failed to create session run")
552
- client.close()
553
- return None
554
-
555
- run_id = result.get("id")
556
-
557
- # Log metrics
558
- metrics = []
559
- if parsed.get("total_tokens"):
560
- metrics.append({"key": "tokens", "value": parsed["total_tokens"], "step": 1})
561
- if parsed.get("message_count"):
562
- metrics.append({"key": "messages", "value": parsed["message_count"], "step": 1})
563
- if parsed.get("user_message_count"):
564
- metrics.append({"key": "user_messages", "value": parsed["user_message_count"], "step": 1})
565
- if parsed.get("files_touched"):
566
- metrics.append({"key": "files_touched", "value": len(parsed["files_touched"]), "step": 1})
567
-
568
- if metrics and run_id:
569
- client.post_metrics(run_id, metrics)
570
-
571
- # Log files touched as summary
572
- if parsed.get("files_touched") and run_id:
573
- client.update_run(run_id, {
574
- "summary": {
575
- "files_touched": len(parsed["files_touched"]),
576
- "tools_used": len(parsed.get("tools_used", [])),
577
- "tokens": parsed.get("total_tokens", 0),
578
- }
579
- })
580
-
581
603
  client.close()
582
- return run_id
604
+ return result.get("id") if result else None
583
605
 
584
606
 
585
607
  def _format_session_notes(parsed: dict) -> str:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "openrunner-sdk"
3
- version = "2.8.0"
3
+ version = "2.9.0"
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
File without changes