empathy-framework 5.0.1__py3-none-any.whl → 5.1.0__py3-none-any.whl

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 (61) hide show
  1. {empathy_framework-5.0.1.dist-info → empathy_framework-5.1.0.dist-info}/METADATA +311 -150
  2. {empathy_framework-5.0.1.dist-info → empathy_framework-5.1.0.dist-info}/RECORD +60 -33
  3. empathy_framework-5.1.0.dist-info/licenses/LICENSE +201 -0
  4. empathy_framework-5.1.0.dist-info/licenses/LICENSE_CHANGE_ANNOUNCEMENT.md +101 -0
  5. empathy_llm_toolkit/providers.py +175 -35
  6. empathy_llm_toolkit/utils/tokens.py +150 -30
  7. empathy_os/__init__.py +1 -1
  8. empathy_os/cli/commands/batch.py +256 -0
  9. empathy_os/cli/commands/cache.py +248 -0
  10. empathy_os/cli/commands/inspect.py +1 -2
  11. empathy_os/cli/commands/metrics.py +1 -1
  12. empathy_os/cli/commands/routing.py +285 -0
  13. empathy_os/cli/commands/workflow.py +2 -1
  14. empathy_os/cli/parsers/__init__.py +6 -0
  15. empathy_os/cli/parsers/batch.py +118 -0
  16. empathy_os/cli/parsers/cache 2.py +65 -0
  17. empathy_os/cli/parsers/cache.py +65 -0
  18. empathy_os/cli/parsers/routing.py +110 -0
  19. empathy_os/cli_minimal.py +3 -3
  20. empathy_os/cli_router 2.py +416 -0
  21. empathy_os/dashboard/__init__.py +1 -2
  22. empathy_os/dashboard/app 2.py +512 -0
  23. empathy_os/dashboard/app.py +1 -1
  24. empathy_os/dashboard/simple_server 2.py +403 -0
  25. empathy_os/dashboard/standalone_server 2.py +536 -0
  26. empathy_os/dashboard/standalone_server.py +22 -11
  27. empathy_os/memory/types 2.py +441 -0
  28. empathy_os/metrics/collector.py +31 -0
  29. empathy_os/models/__init__.py +19 -0
  30. empathy_os/models/adaptive_routing 2.py +437 -0
  31. empathy_os/models/auth_cli.py +444 -0
  32. empathy_os/models/auth_strategy.py +450 -0
  33. empathy_os/models/token_estimator.py +21 -13
  34. empathy_os/project_index/scanner_parallel 2.py +291 -0
  35. empathy_os/telemetry/agent_coordination 2.py +478 -0
  36. empathy_os/telemetry/agent_coordination.py +14 -16
  37. empathy_os/telemetry/agent_tracking 2.py +350 -0
  38. empathy_os/telemetry/agent_tracking.py +18 -20
  39. empathy_os/telemetry/approval_gates 2.py +563 -0
  40. empathy_os/telemetry/approval_gates.py +27 -39
  41. empathy_os/telemetry/event_streaming 2.py +405 -0
  42. empathy_os/telemetry/event_streaming.py +22 -22
  43. empathy_os/telemetry/feedback_loop 2.py +557 -0
  44. empathy_os/telemetry/feedback_loop.py +14 -17
  45. empathy_os/workflows/__init__.py +8 -0
  46. empathy_os/workflows/autonomous_test_gen.py +569 -0
  47. empathy_os/workflows/batch_processing.py +56 -10
  48. empathy_os/workflows/bug_predict.py +45 -0
  49. empathy_os/workflows/code_review.py +92 -22
  50. empathy_os/workflows/document_gen.py +594 -62
  51. empathy_os/workflows/llm_base.py +363 -0
  52. empathy_os/workflows/perf_audit.py +69 -0
  53. empathy_os/workflows/release_prep.py +54 -0
  54. empathy_os/workflows/security_audit.py +154 -79
  55. empathy_os/workflows/test_gen.py +60 -0
  56. empathy_os/workflows/test_gen_behavioral.py +477 -0
  57. empathy_os/workflows/test_gen_parallel.py +341 -0
  58. empathy_framework-5.0.1.dist-info/licenses/LICENSE +0 -139
  59. {empathy_framework-5.0.1.dist-info → empathy_framework-5.1.0.dist-info}/WHEEL +0 -0
  60. {empathy_framework-5.0.1.dist-info → empathy_framework-5.1.0.dist-info}/entry_points.txt +0 -0
  61. {empathy_framework-5.0.1.dist-info → empathy_framework-5.1.0.dist-info}/top_level.txt +0 -0
@@ -450,6 +450,7 @@ class BugPredictionWorkflow(BaseWorkflow):
450
450
  self,
451
451
  risk_threshold: float | None = None,
452
452
  patterns_dir: str = "./patterns",
453
+ enable_auth_strategy: bool = True,
453
454
  **kwargs: Any,
454
455
  ):
455
456
  """Initialize bug prediction workflow.
@@ -458,6 +459,8 @@ class BugPredictionWorkflow(BaseWorkflow):
458
459
  risk_threshold: Minimum risk score to trigger premium recommendations
459
460
  (defaults to config value or 0.7)
460
461
  patterns_dir: Directory containing learned patterns
462
+ enable_auth_strategy: If True, use intelligent subscription vs API routing
463
+ based on codebase size (default True)
461
464
  **kwargs: Additional arguments passed to BaseWorkflow
462
465
 
463
466
  """
@@ -481,8 +484,10 @@ class BugPredictionWorkflow(BaseWorkflow):
481
484
  else self._bug_predict_config["risk_threshold"]
482
485
  )
483
486
  self.patterns_dir = patterns_dir
487
+ self.enable_auth_strategy = enable_auth_strategy
484
488
  self._risk_score: float = 0.0
485
489
  self._bug_patterns: list[dict] = []
490
+ self._auth_mode_used: str | None = None # Track which auth was recommended
486
491
  self._load_patterns()
487
492
 
488
493
  def _load_patterns(self) -> None:
@@ -575,6 +580,45 @@ class BugPredictionWorkflow(BaseWorkflow):
575
580
  config_exclude_patterns = self._bug_predict_config.get("exclude_files", [])
576
581
  acceptable_contexts = self._bug_predict_config.get("acceptable_exception_contexts", None)
577
582
 
583
+ # === AUTH STRATEGY INTEGRATION ===
584
+ # Detect codebase size and recommend auth mode (first stage only)
585
+ if self.enable_auth_strategy:
586
+ try:
587
+ from empathy_os.models import (
588
+ count_lines_of_code,
589
+ get_auth_strategy,
590
+ get_module_size_category,
591
+ )
592
+
593
+ # Calculate codebase size
594
+ codebase_lines = 0
595
+ target = Path(target_path)
596
+ if target.exists():
597
+ codebase_lines = count_lines_of_code(str(target))
598
+
599
+ # Get auth strategy and recommendation
600
+ strategy = get_auth_strategy()
601
+ if strategy:
602
+ # Get recommended auth mode
603
+ recommended_mode = strategy.get_recommended_mode(codebase_lines)
604
+ self._auth_mode_used = recommended_mode.value
605
+
606
+ # Get size category
607
+ size_category = get_module_size_category(codebase_lines)
608
+
609
+ # Log recommendation
610
+ logger.info(
611
+ f"Auth Strategy: {size_category.value} codebase ({codebase_lines} lines) "
612
+ f"-> {recommended_mode.value}",
613
+ )
614
+ except ImportError:
615
+ # Auth strategy module not available - continue without it
616
+ logger.debug("Auth strategy module not available")
617
+ except Exception as e:
618
+ # Don't fail the workflow if auth strategy detection fails
619
+ logger.warning(f"Auth strategy detection failed: {e}")
620
+ # === END AUTH STRATEGY ===/
621
+
578
622
  # Walk directory and collect file info
579
623
  target = Path(target_path)
580
624
  if target.exists():
@@ -878,6 +922,7 @@ Provide detailed recommendations for preventing bugs."""
878
922
  "recommendation_count": len(top_risks),
879
923
  "model_tier_used": tier.value,
880
924
  "overall_risk_score": input_data.get("overall_risk_score", 0),
925
+ "auth_mode_used": self._auth_mode_used, # Track recommended auth mode
881
926
  }
882
927
 
883
928
  # Merge parsed XML data if available
@@ -57,6 +57,7 @@ class CodeReviewWorkflow(BaseWorkflow):
57
57
  core_modules: list[str] | None = None,
58
58
  use_crew: bool = True,
59
59
  crew_config: dict | None = None,
60
+ enable_auth_strategy: bool = True,
60
61
  **kwargs: Any,
61
62
  ):
62
63
  """Initialize workflow.
@@ -66,6 +67,8 @@ class CodeReviewWorkflow(BaseWorkflow):
66
67
  core_modules: List of module paths considered "core" (trigger premium).
67
68
  use_crew: Enable CodeReviewCrew for comprehensive 5-agent analysis (default: True).
68
69
  crew_config: Configuration dict for CodeReviewCrew.
70
+ enable_auth_strategy: If True, use intelligent subscription vs API routing
71
+ based on module size (default True).
69
72
 
70
73
  """
71
74
  super().__init__(**kwargs)
@@ -79,10 +82,12 @@ class CodeReviewWorkflow(BaseWorkflow):
79
82
  ]
80
83
  self.use_crew = use_crew
81
84
  self.crew_config = crew_config or {}
85
+ self.enable_auth_strategy = enable_auth_strategy
82
86
  self._needs_architect_review: bool = False
83
87
  self._change_type: str = "unknown"
84
88
  self._crew: Any = None
85
89
  self._crew_available = False
90
+ self._auth_mode_used: str | None = None
86
91
 
87
92
  # Dynamically configure stages based on crew setting
88
93
  if use_crew:
@@ -296,6 +301,56 @@ class CodeReviewWorkflow(BaseWorkflow):
296
301
  # Mark as project-level review
297
302
  input_data["is_project_review"] = True
298
303
 
304
+ # === AUTH STRATEGY INTEGRATION ===
305
+ if self.enable_auth_strategy:
306
+ try:
307
+ import logging
308
+ from pathlib import Path
309
+
310
+ from empathy_os.models import (
311
+ count_lines_of_code,
312
+ get_auth_strategy,
313
+ get_module_size_category,
314
+ )
315
+
316
+ logger = logging.getLogger(__name__)
317
+
318
+ # Calculate module size (for file) or total LOC (for directory)
319
+ target_path = target or diff
320
+ total_lines = 0
321
+ if target_path:
322
+ target_obj = Path(target_path)
323
+ if target_obj.exists():
324
+ if target_obj.is_file():
325
+ total_lines = count_lines_of_code(target_obj)
326
+ elif target_obj.is_dir():
327
+ for py_file in target_obj.rglob("*.py"):
328
+ try:
329
+ total_lines += count_lines_of_code(py_file)
330
+ except Exception:
331
+ pass
332
+
333
+ if total_lines > 0:
334
+ strategy = get_auth_strategy()
335
+ recommended_mode = strategy.get_recommended_mode(total_lines)
336
+ self._auth_mode_used = recommended_mode.value
337
+
338
+ size_category = get_module_size_category(total_lines)
339
+ logger.info(
340
+ f"Code review target: {target_path} ({total_lines:,} LOC, {size_category})"
341
+ )
342
+ logger.info(f"Recommended auth mode: {recommended_mode.value}")
343
+
344
+ cost_estimate = strategy.estimate_cost(total_lines, recommended_mode)
345
+ if recommended_mode.value == "subscription":
346
+ logger.info(f"Cost: {cost_estimate['quota_cost']}")
347
+ else:
348
+ logger.info(f"Cost: ~${cost_estimate['monetary_cost']:.4f}")
349
+
350
+ except Exception as e:
351
+ logger = logging.getLogger(__name__)
352
+ logger.warning(f"Auth strategy detection failed: {e}")
353
+
299
354
  system = """You are a code review classifier. Analyze the code and classify:
300
355
  1. Change type: bug_fix, feature, refactor, docs, test, config, or security
301
356
  2. Complexity: low, medium, high
@@ -590,28 +645,42 @@ Code to review:
590
645
  "Code will proceed to architectural review."
591
646
  )
592
647
 
593
- return (
594
- {
595
- "scan_results": response,
596
- "findings": all_findings, # NEW: structured findings for UI
597
- "summary": summary, # NEW: summary statistics
598
- "security_findings": security_findings, # Keep for backward compat
599
- "bug_patterns": [],
600
- "quality_issues": [],
601
- "has_critical_issues": has_critical,
602
- "security_score": 70 if has_critical else 90,
603
- "needs_architect_review": input_data.get("needs_architect_review", False)
604
- or has_critical,
605
- "code_to_review": code_to_review,
606
- "classification": classification,
607
- "external_audit_included": external_audit is not None,
608
- "external_audit_risk_score": (
609
- external_audit.get("risk_score", 0) if external_audit else 0
610
- ),
611
- },
612
- input_tokens,
613
- output_tokens,
614
- )
648
+ # Determine preliminary verdict based on scan
649
+ if has_critical:
650
+ preliminary_verdict = "request_changes"
651
+ elif security_score >= 90:
652
+ preliminary_verdict = "approve"
653
+ else:
654
+ preliminary_verdict = "approve_with_suggestions"
655
+
656
+ result = {
657
+ "scan_results": response,
658
+ "findings": all_findings, # NEW: structured findings for UI
659
+ "summary": summary, # NEW: summary statistics
660
+ "security_findings": security_findings, # Keep for backward compat
661
+ "bug_patterns": [],
662
+ "quality_issues": [],
663
+ "has_critical_issues": has_critical,
664
+ "security_score": 70 if has_critical else 90,
665
+ "verdict": preliminary_verdict, # Add verdict for when architect_review is skipped
666
+ "needs_architect_review": input_data.get("needs_architect_review", False)
667
+ or has_critical,
668
+ "code_to_review": code_to_review,
669
+ "classification": classification,
670
+ "external_audit_included": external_audit is not None,
671
+ "external_audit_risk_score": (
672
+ external_audit.get("risk_score", 0) if external_audit else 0
673
+ ),
674
+ "auth_mode_used": self._auth_mode_used, # Track auth mode
675
+ "model_tier_used": tier.value, # Track model tier
676
+ }
677
+
678
+ # Generate formatted report (for when architect_review is skipped)
679
+ formatted_report = format_code_review_report(result, input_data)
680
+ result["formatted_report"] = formatted_report
681
+ result["display_output"] = formatted_report
682
+
683
+ return (result, input_tokens, output_tokens)
615
684
 
616
685
  def _merge_external_audit(
617
686
  self,
@@ -796,6 +865,7 @@ Provide actionable, specific feedback."""
796
865
  "verdict": verdict,
797
866
  "recommendations": [],
798
867
  "model_tier_used": tier.value,
868
+ "auth_mode_used": self._auth_mode_used,
799
869
  }
800
870
 
801
871
  # Merge parsed XML data if available