empathy-framework 3.7.0__py3-none-any.whl → 3.8.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.
- coach_wizards/code_reviewer_README.md +60 -0
- coach_wizards/code_reviewer_wizard.py +180 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/METADATA +148 -11
- empathy_framework-3.8.0.dist-info/RECORD +333 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/top_level.txt +5 -1
- empathy_healthcare_plugin/monitors/__init__.py +9 -0
- empathy_healthcare_plugin/monitors/clinical_protocol_monitor.py +315 -0
- empathy_healthcare_plugin/monitors/monitoring/__init__.py +44 -0
- empathy_healthcare_plugin/monitors/monitoring/protocol_checker.py +300 -0
- empathy_healthcare_plugin/monitors/monitoring/protocol_loader.py +214 -0
- empathy_healthcare_plugin/monitors/monitoring/sensor_parsers.py +306 -0
- empathy_healthcare_plugin/monitors/monitoring/trajectory_analyzer.py +389 -0
- empathy_llm_toolkit/agent_factory/__init__.py +53 -0
- empathy_llm_toolkit/agent_factory/adapters/__init__.py +85 -0
- empathy_llm_toolkit/agent_factory/adapters/autogen_adapter.py +312 -0
- empathy_llm_toolkit/agent_factory/adapters/crewai_adapter.py +454 -0
- empathy_llm_toolkit/agent_factory/adapters/haystack_adapter.py +298 -0
- empathy_llm_toolkit/agent_factory/adapters/langchain_adapter.py +362 -0
- empathy_llm_toolkit/agent_factory/adapters/langgraph_adapter.py +333 -0
- empathy_llm_toolkit/agent_factory/adapters/native.py +228 -0
- empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +426 -0
- empathy_llm_toolkit/agent_factory/base.py +305 -0
- empathy_llm_toolkit/agent_factory/crews/__init__.py +67 -0
- empathy_llm_toolkit/agent_factory/crews/code_review.py +1113 -0
- empathy_llm_toolkit/agent_factory/crews/health_check.py +1246 -0
- empathy_llm_toolkit/agent_factory/crews/refactoring.py +1128 -0
- empathy_llm_toolkit/agent_factory/crews/security_audit.py +1018 -0
- empathy_llm_toolkit/agent_factory/decorators.py +286 -0
- empathy_llm_toolkit/agent_factory/factory.py +558 -0
- empathy_llm_toolkit/agent_factory/framework.py +192 -0
- empathy_llm_toolkit/agent_factory/memory_integration.py +324 -0
- empathy_llm_toolkit/agent_factory/resilient.py +320 -0
- empathy_llm_toolkit/cli/__init__.py +8 -0
- empathy_llm_toolkit/cli/sync_claude.py +487 -0
- empathy_llm_toolkit/code_health.py +150 -3
- empathy_llm_toolkit/config/__init__.py +29 -0
- empathy_llm_toolkit/config/unified.py +295 -0
- empathy_llm_toolkit/routing/__init__.py +32 -0
- empathy_llm_toolkit/routing/model_router.py +362 -0
- empathy_llm_toolkit/security/IMPLEMENTATION_SUMMARY.md +413 -0
- empathy_llm_toolkit/security/PHASE2_COMPLETE.md +384 -0
- empathy_llm_toolkit/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
- empathy_llm_toolkit/security/QUICK_REFERENCE.md +316 -0
- empathy_llm_toolkit/security/README.md +262 -0
- empathy_llm_toolkit/security/__init__.py +62 -0
- empathy_llm_toolkit/security/audit_logger.py +929 -0
- empathy_llm_toolkit/security/audit_logger_example.py +152 -0
- empathy_llm_toolkit/security/pii_scrubber.py +640 -0
- empathy_llm_toolkit/security/secrets_detector.py +678 -0
- empathy_llm_toolkit/security/secrets_detector_example.py +304 -0
- empathy_llm_toolkit/security/secure_memdocs.py +1192 -0
- empathy_llm_toolkit/security/secure_memdocs_example.py +278 -0
- empathy_llm_toolkit/wizards/__init__.py +38 -0
- empathy_llm_toolkit/wizards/base_wizard.py +364 -0
- empathy_llm_toolkit/wizards/customer_support_wizard.py +190 -0
- empathy_llm_toolkit/wizards/healthcare_wizard.py +362 -0
- empathy_llm_toolkit/wizards/patient_assessment_README.md +64 -0
- empathy_llm_toolkit/wizards/patient_assessment_wizard.py +193 -0
- empathy_llm_toolkit/wizards/technology_wizard.py +194 -0
- empathy_os/__init__.py +52 -52
- empathy_os/adaptive/__init__.py +13 -0
- empathy_os/adaptive/task_complexity.py +127 -0
- empathy_os/cache/__init__.py +117 -0
- empathy_os/cache/base.py +166 -0
- empathy_os/cache/dependency_manager.py +253 -0
- empathy_os/cache/hash_only.py +248 -0
- empathy_os/cache/hybrid.py +390 -0
- empathy_os/cache/storage.py +282 -0
- empathy_os/cli.py +118 -8
- empathy_os/cli_unified.py +121 -1
- empathy_os/config/__init__.py +63 -0
- empathy_os/config/xml_config.py +239 -0
- empathy_os/config.py +2 -1
- empathy_os/dashboard/__init__.py +15 -0
- empathy_os/dashboard/server.py +743 -0
- empathy_os/memory/__init__.py +195 -0
- empathy_os/memory/claude_memory.py +466 -0
- empathy_os/memory/config.py +224 -0
- empathy_os/memory/control_panel.py +1298 -0
- empathy_os/memory/edges.py +179 -0
- empathy_os/memory/graph.py +567 -0
- empathy_os/memory/long_term.py +1194 -0
- empathy_os/memory/nodes.py +179 -0
- empathy_os/memory/redis_bootstrap.py +540 -0
- empathy_os/memory/security/__init__.py +31 -0
- empathy_os/memory/security/audit_logger.py +930 -0
- empathy_os/memory/security/pii_scrubber.py +640 -0
- empathy_os/memory/security/secrets_detector.py +678 -0
- empathy_os/memory/short_term.py +2119 -0
- empathy_os/memory/storage/__init__.py +15 -0
- empathy_os/memory/summary_index.py +583 -0
- empathy_os/memory/unified.py +619 -0
- empathy_os/metrics/__init__.py +12 -0
- empathy_os/metrics/prompt_metrics.py +190 -0
- empathy_os/models/__init__.py +136 -0
- empathy_os/models/__main__.py +13 -0
- empathy_os/models/cli.py +655 -0
- empathy_os/models/empathy_executor.py +354 -0
- empathy_os/models/executor.py +252 -0
- empathy_os/models/fallback.py +671 -0
- empathy_os/models/provider_config.py +563 -0
- empathy_os/models/registry.py +382 -0
- empathy_os/models/tasks.py +302 -0
- empathy_os/models/telemetry.py +548 -0
- empathy_os/models/token_estimator.py +378 -0
- empathy_os/models/validation.py +274 -0
- empathy_os/monitoring/__init__.py +52 -0
- empathy_os/monitoring/alerts.py +23 -0
- empathy_os/monitoring/alerts_cli.py +268 -0
- empathy_os/monitoring/multi_backend.py +271 -0
- empathy_os/monitoring/otel_backend.py +363 -0
- empathy_os/optimization/__init__.py +19 -0
- empathy_os/optimization/context_optimizer.py +272 -0
- empathy_os/plugins/__init__.py +28 -0
- empathy_os/plugins/base.py +361 -0
- empathy_os/plugins/registry.py +268 -0
- empathy_os/project_index/__init__.py +30 -0
- empathy_os/project_index/cli.py +335 -0
- empathy_os/project_index/crew_integration.py +430 -0
- empathy_os/project_index/index.py +425 -0
- empathy_os/project_index/models.py +501 -0
- empathy_os/project_index/reports.py +473 -0
- empathy_os/project_index/scanner.py +538 -0
- empathy_os/prompts/__init__.py +61 -0
- empathy_os/prompts/config.py +77 -0
- empathy_os/prompts/context.py +177 -0
- empathy_os/prompts/parser.py +285 -0
- empathy_os/prompts/registry.py +313 -0
- empathy_os/prompts/templates.py +208 -0
- empathy_os/resilience/__init__.py +56 -0
- empathy_os/resilience/circuit_breaker.py +256 -0
- empathy_os/resilience/fallback.py +179 -0
- empathy_os/resilience/health.py +300 -0
- empathy_os/resilience/retry.py +209 -0
- empathy_os/resilience/timeout.py +135 -0
- empathy_os/routing/__init__.py +43 -0
- empathy_os/routing/chain_executor.py +433 -0
- empathy_os/routing/classifier.py +217 -0
- empathy_os/routing/smart_router.py +234 -0
- empathy_os/routing/wizard_registry.py +307 -0
- empathy_os/trust/__init__.py +28 -0
- empathy_os/trust/circuit_breaker.py +579 -0
- empathy_os/validation/__init__.py +19 -0
- empathy_os/validation/xml_validator.py +281 -0
- empathy_os/wizard_factory_cli.py +170 -0
- empathy_os/workflows/__init__.py +360 -0
- empathy_os/workflows/base.py +1660 -0
- empathy_os/workflows/bug_predict.py +962 -0
- empathy_os/workflows/code_review.py +960 -0
- empathy_os/workflows/code_review_adapters.py +310 -0
- empathy_os/workflows/code_review_pipeline.py +720 -0
- empathy_os/workflows/config.py +600 -0
- empathy_os/workflows/dependency_check.py +648 -0
- empathy_os/workflows/document_gen.py +1069 -0
- empathy_os/workflows/documentation_orchestrator.py +1205 -0
- empathy_os/workflows/health_check.py +679 -0
- empathy_os/workflows/keyboard_shortcuts/__init__.py +39 -0
- empathy_os/workflows/keyboard_shortcuts/generators.py +386 -0
- empathy_os/workflows/keyboard_shortcuts/parsers.py +414 -0
- empathy_os/workflows/keyboard_shortcuts/prompts.py +295 -0
- empathy_os/workflows/keyboard_shortcuts/schema.py +193 -0
- empathy_os/workflows/keyboard_shortcuts/workflow.py +505 -0
- empathy_os/workflows/manage_documentation.py +804 -0
- empathy_os/workflows/new_sample_workflow1.py +146 -0
- empathy_os/workflows/new_sample_workflow1_README.md +150 -0
- empathy_os/workflows/perf_audit.py +687 -0
- empathy_os/workflows/pr_review.py +748 -0
- empathy_os/workflows/progress.py +445 -0
- empathy_os/workflows/progress_server.py +322 -0
- empathy_os/workflows/refactor_plan.py +693 -0
- empathy_os/workflows/release_prep.py +808 -0
- empathy_os/workflows/research_synthesis.py +404 -0
- empathy_os/workflows/secure_release.py +585 -0
- empathy_os/workflows/security_adapters.py +297 -0
- empathy_os/workflows/security_audit.py +1046 -0
- empathy_os/workflows/step_config.py +234 -0
- empathy_os/workflows/test5.py +125 -0
- empathy_os/workflows/test5_README.md +158 -0
- empathy_os/workflows/test_gen.py +1855 -0
- empathy_os/workflows/test_lifecycle.py +526 -0
- empathy_os/workflows/test_maintenance.py +626 -0
- empathy_os/workflows/test_maintenance_cli.py +590 -0
- empathy_os/workflows/test_maintenance_crew.py +821 -0
- empathy_os/workflows/xml_enhanced_crew.py +285 -0
- empathy_software_plugin/cli/__init__.py +120 -0
- empathy_software_plugin/cli/inspect.py +362 -0
- empathy_software_plugin/cli.py +3 -1
- empathy_software_plugin/wizards/__init__.py +42 -0
- empathy_software_plugin/wizards/advanced_debugging_wizard.py +392 -0
- empathy_software_plugin/wizards/agent_orchestration_wizard.py +511 -0
- empathy_software_plugin/wizards/ai_collaboration_wizard.py +503 -0
- empathy_software_plugin/wizards/ai_context_wizard.py +441 -0
- empathy_software_plugin/wizards/ai_documentation_wizard.py +503 -0
- empathy_software_plugin/wizards/base_wizard.py +288 -0
- empathy_software_plugin/wizards/book_chapter_wizard.py +519 -0
- empathy_software_plugin/wizards/code_review_wizard.py +606 -0
- empathy_software_plugin/wizards/debugging/__init__.py +50 -0
- empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +414 -0
- empathy_software_plugin/wizards/debugging/config_loaders.py +442 -0
- empathy_software_plugin/wizards/debugging/fix_applier.py +469 -0
- empathy_software_plugin/wizards/debugging/language_patterns.py +383 -0
- empathy_software_plugin/wizards/debugging/linter_parsers.py +470 -0
- empathy_software_plugin/wizards/debugging/verification.py +369 -0
- empathy_software_plugin/wizards/enhanced_testing_wizard.py +537 -0
- empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +816 -0
- empathy_software_plugin/wizards/multi_model_wizard.py +501 -0
- empathy_software_plugin/wizards/pattern_extraction_wizard.py +422 -0
- empathy_software_plugin/wizards/pattern_retriever_wizard.py +400 -0
- empathy_software_plugin/wizards/performance/__init__.py +9 -0
- empathy_software_plugin/wizards/performance/bottleneck_detector.py +221 -0
- empathy_software_plugin/wizards/performance/profiler_parsers.py +278 -0
- empathy_software_plugin/wizards/performance/trajectory_analyzer.py +429 -0
- empathy_software_plugin/wizards/performance_profiling_wizard.py +305 -0
- empathy_software_plugin/wizards/prompt_engineering_wizard.py +425 -0
- empathy_software_plugin/wizards/rag_pattern_wizard.py +461 -0
- empathy_software_plugin/wizards/security/__init__.py +32 -0
- empathy_software_plugin/wizards/security/exploit_analyzer.py +290 -0
- empathy_software_plugin/wizards/security/owasp_patterns.py +241 -0
- empathy_software_plugin/wizards/security/vulnerability_scanner.py +604 -0
- empathy_software_plugin/wizards/security_analysis_wizard.py +322 -0
- empathy_software_plugin/wizards/security_learning_wizard.py +740 -0
- empathy_software_plugin/wizards/tech_debt_wizard.py +726 -0
- empathy_software_plugin/wizards/testing/__init__.py +27 -0
- empathy_software_plugin/wizards/testing/coverage_analyzer.py +459 -0
- empathy_software_plugin/wizards/testing/quality_analyzer.py +531 -0
- empathy_software_plugin/wizards/testing/test_suggester.py +533 -0
- empathy_software_plugin/wizards/testing_wizard.py +274 -0
- hot_reload/README.md +473 -0
- hot_reload/__init__.py +62 -0
- hot_reload/config.py +84 -0
- hot_reload/integration.py +228 -0
- hot_reload/reloader.py +298 -0
- hot_reload/watcher.py +179 -0
- hot_reload/websocket.py +176 -0
- scaffolding/README.md +589 -0
- scaffolding/__init__.py +35 -0
- scaffolding/__main__.py +14 -0
- scaffolding/cli.py +240 -0
- test_generator/__init__.py +38 -0
- test_generator/__main__.py +14 -0
- test_generator/cli.py +226 -0
- test_generator/generator.py +325 -0
- test_generator/risk_analyzer.py +216 -0
- workflow_patterns/__init__.py +33 -0
- workflow_patterns/behavior.py +249 -0
- workflow_patterns/core.py +76 -0
- workflow_patterns/output.py +99 -0
- workflow_patterns/registry.py +255 -0
- workflow_patterns/structural.py +288 -0
- workflow_scaffolding/__init__.py +11 -0
- workflow_scaffolding/__main__.py +12 -0
- workflow_scaffolding/cli.py +206 -0
- workflow_scaffolding/generator.py +265 -0
- agents/code_inspection/patterns/inspection/recurring_B112.json +0 -18
- agents/code_inspection/patterns/inspection/recurring_F541.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_FORMAT.json +0 -25
- agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_null_001.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_builtin.json +0 -16
- agents/compliance_anticipation_agent.py +0 -1422
- agents/compliance_db.py +0 -339
- agents/epic_integration_wizard.py +0 -530
- agents/notifications.py +0 -291
- agents/trust_building_behaviors.py +0 -872
- empathy_framework-3.7.0.dist-info/RECORD +0 -105
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/WHEEL +0 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/entry_points.txt +0 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/licenses/LICENSE +0 -0
- /empathy_os/{monitoring.py → agent_monitoring.py} +0 -0
|
@@ -9,6 +9,7 @@ Licensed under Fair Source 0.9
|
|
|
9
9
|
|
|
10
10
|
import asyncio
|
|
11
11
|
import json
|
|
12
|
+
import logging
|
|
12
13
|
import shutil
|
|
13
14
|
import subprocess
|
|
14
15
|
from dataclasses import dataclass, field
|
|
@@ -17,6 +18,8 @@ from enum import Enum
|
|
|
17
18
|
from pathlib import Path
|
|
18
19
|
from typing import Any
|
|
19
20
|
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
20
23
|
|
|
21
24
|
class HealthStatus(Enum):
|
|
22
25
|
"""Health check result status."""
|
|
@@ -311,13 +314,23 @@ class HealthCheckRunner:
|
|
|
311
314
|
handler,
|
|
312
315
|
config: dict,
|
|
313
316
|
) -> CheckResult:
|
|
314
|
-
"""Run a check handler asynchronously.
|
|
317
|
+
"""Run a check handler asynchronously.
|
|
318
|
+
|
|
319
|
+
This uses broad exception handling intentionally for graceful degradation.
|
|
320
|
+
Health checks are optional features - the system should continue even if some checks fail.
|
|
321
|
+
|
|
322
|
+
Note:
|
|
323
|
+
Full exception context is preserved via logger.exception() for debugging.
|
|
324
|
+
"""
|
|
315
325
|
start_time = datetime.now()
|
|
316
326
|
try:
|
|
317
327
|
result: CheckResult = await asyncio.to_thread(handler, config)
|
|
318
328
|
result.duration_ms = int((datetime.now() - start_time).total_seconds() * 1000)
|
|
319
329
|
return result
|
|
320
330
|
except Exception as e:
|
|
331
|
+
# INTENTIONAL: Broad exception handler for graceful degradation of optional checks
|
|
332
|
+
# Full traceback preserved for debugging
|
|
333
|
+
logger.exception(f"Health check failed for {category.value}: {e}")
|
|
321
334
|
return CheckResult(
|
|
322
335
|
category=category,
|
|
323
336
|
status=HealthStatus.ERROR,
|
|
@@ -390,7 +403,30 @@ class HealthCheckRunner:
|
|
|
390
403
|
details={"total_files_checked": len({i.file_path for i in issues}) or "all"},
|
|
391
404
|
)
|
|
392
405
|
|
|
406
|
+
except json.JSONDecodeError as e:
|
|
407
|
+
# Tool output not in expected JSON format
|
|
408
|
+
logger.warning(f"Lint check JSON parse error ({tool}): {e}")
|
|
409
|
+
return CheckResult(
|
|
410
|
+
category=CheckCategory.LINT,
|
|
411
|
+
status=HealthStatus.ERROR,
|
|
412
|
+
score=0,
|
|
413
|
+
tool_used=tool,
|
|
414
|
+
details={"error": f"Failed to parse {tool} output: {e}"},
|
|
415
|
+
)
|
|
416
|
+
except subprocess.SubprocessError as e:
|
|
417
|
+
# Tool execution failed
|
|
418
|
+
logger.error(f"Lint check subprocess error ({tool}): {e}")
|
|
419
|
+
return CheckResult(
|
|
420
|
+
category=CheckCategory.LINT,
|
|
421
|
+
status=HealthStatus.ERROR,
|
|
422
|
+
score=0,
|
|
423
|
+
tool_used=tool,
|
|
424
|
+
details={"error": f"Failed to run {tool}: {e}"},
|
|
425
|
+
)
|
|
393
426
|
except Exception as e:
|
|
427
|
+
# Unexpected errors - preserve full context for debugging
|
|
428
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional check
|
|
429
|
+
logger.exception(f"Unexpected error in lint check ({tool}): {e}")
|
|
394
430
|
return CheckResult(
|
|
395
431
|
category=CheckCategory.LINT,
|
|
396
432
|
status=HealthStatus.ERROR,
|
|
@@ -475,7 +511,20 @@ class HealthCheckRunner:
|
|
|
475
511
|
details={"files_need_formatting": len(issues)},
|
|
476
512
|
)
|
|
477
513
|
|
|
514
|
+
except subprocess.SubprocessError as e:
|
|
515
|
+
# Tool execution failed
|
|
516
|
+
logger.error(f"Format check subprocess error ({tool}): {e}")
|
|
517
|
+
return CheckResult(
|
|
518
|
+
category=CheckCategory.FORMAT,
|
|
519
|
+
status=HealthStatus.ERROR,
|
|
520
|
+
score=0,
|
|
521
|
+
tool_used=tool,
|
|
522
|
+
details={"error": f"Failed to run {tool}: {e}"},
|
|
523
|
+
)
|
|
478
524
|
except Exception as e:
|
|
525
|
+
# Unexpected errors - preserve full context for debugging
|
|
526
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional check
|
|
527
|
+
logger.exception(f"Unexpected error in format check ({tool}): {e}")
|
|
479
528
|
return CheckResult(
|
|
480
529
|
category=CheckCategory.FORMAT,
|
|
481
530
|
status=HealthStatus.ERROR,
|
|
@@ -569,7 +618,30 @@ class HealthCheckRunner:
|
|
|
569
618
|
details={"type_errors": len(issues)},
|
|
570
619
|
)
|
|
571
620
|
|
|
621
|
+
except json.JSONDecodeError as e:
|
|
622
|
+
# Tool output not in expected JSON format (pyright specific)
|
|
623
|
+
logger.warning(f"Type check JSON parse error ({tool}): {e}")
|
|
624
|
+
return CheckResult(
|
|
625
|
+
category=CheckCategory.TYPES,
|
|
626
|
+
status=HealthStatus.ERROR,
|
|
627
|
+
score=0,
|
|
628
|
+
tool_used=tool,
|
|
629
|
+
details={"error": f"Failed to parse {tool} output: {e}"},
|
|
630
|
+
)
|
|
631
|
+
except subprocess.SubprocessError as e:
|
|
632
|
+
# Tool execution failed
|
|
633
|
+
logger.error(f"Type check subprocess error ({tool}): {e}")
|
|
634
|
+
return CheckResult(
|
|
635
|
+
category=CheckCategory.TYPES,
|
|
636
|
+
status=HealthStatus.ERROR,
|
|
637
|
+
score=0,
|
|
638
|
+
tool_used=tool,
|
|
639
|
+
details={"error": f"Failed to run {tool}: {e}"},
|
|
640
|
+
)
|
|
572
641
|
except Exception as e:
|
|
642
|
+
# Unexpected errors - preserve full context for debugging
|
|
643
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional check
|
|
644
|
+
logger.exception(f"Unexpected error in type check ({tool}): {e}")
|
|
573
645
|
return CheckResult(
|
|
574
646
|
category=CheckCategory.TYPES,
|
|
575
647
|
status=HealthStatus.ERROR,
|
|
@@ -681,6 +753,8 @@ class HealthCheckRunner:
|
|
|
681
753
|
)
|
|
682
754
|
|
|
683
755
|
except subprocess.TimeoutExpired:
|
|
756
|
+
# Tests took too long - specific timeout error
|
|
757
|
+
logger.error(f"Test check timeout ({tool}): Tests took longer than 5 minutes")
|
|
684
758
|
return CheckResult(
|
|
685
759
|
category=CheckCategory.TESTS,
|
|
686
760
|
status=HealthStatus.ERROR,
|
|
@@ -688,7 +762,20 @@ class HealthCheckRunner:
|
|
|
688
762
|
tool_used=tool,
|
|
689
763
|
details={"error": "Test suite timed out after 5 minutes"},
|
|
690
764
|
)
|
|
765
|
+
except subprocess.SubprocessError as e:
|
|
766
|
+
# Tool execution failed
|
|
767
|
+
logger.error(f"Test check subprocess error ({tool}): {e}")
|
|
768
|
+
return CheckResult(
|
|
769
|
+
category=CheckCategory.TESTS,
|
|
770
|
+
status=HealthStatus.ERROR,
|
|
771
|
+
score=0,
|
|
772
|
+
tool_used=tool,
|
|
773
|
+
details={"error": f"Failed to run {tool}: {e}"},
|
|
774
|
+
)
|
|
691
775
|
except Exception as e:
|
|
776
|
+
# Unexpected errors - preserve full context for debugging
|
|
777
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional check
|
|
778
|
+
logger.exception(f"Unexpected error in test check ({tool}): {e}")
|
|
692
779
|
return CheckResult(
|
|
693
780
|
category=CheckCategory.TESTS,
|
|
694
781
|
status=HealthStatus.ERROR,
|
|
@@ -761,7 +848,30 @@ class HealthCheckRunner:
|
|
|
761
848
|
},
|
|
762
849
|
)
|
|
763
850
|
|
|
851
|
+
except json.JSONDecodeError as e:
|
|
852
|
+
# Tool output not in expected JSON format
|
|
853
|
+
logger.warning(f"Security check JSON parse error ({tool}): {e}")
|
|
854
|
+
return CheckResult(
|
|
855
|
+
category=CheckCategory.SECURITY,
|
|
856
|
+
status=HealthStatus.ERROR,
|
|
857
|
+
score=0,
|
|
858
|
+
tool_used=tool,
|
|
859
|
+
details={"error": f"Failed to parse {tool} output: {e}"},
|
|
860
|
+
)
|
|
861
|
+
except subprocess.SubprocessError as e:
|
|
862
|
+
# Tool execution failed
|
|
863
|
+
logger.error(f"Security check subprocess error ({tool}): {e}")
|
|
864
|
+
return CheckResult(
|
|
865
|
+
category=CheckCategory.SECURITY,
|
|
866
|
+
status=HealthStatus.ERROR,
|
|
867
|
+
score=0,
|
|
868
|
+
tool_used=tool,
|
|
869
|
+
details={"error": f"Failed to run {tool}: {e}"},
|
|
870
|
+
)
|
|
764
871
|
except Exception as e:
|
|
872
|
+
# Unexpected errors - preserve full context for debugging
|
|
873
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional check
|
|
874
|
+
logger.exception(f"Unexpected error in security check ({tool}): {e}")
|
|
765
875
|
return CheckResult(
|
|
766
876
|
category=CheckCategory.SECURITY,
|
|
767
877
|
status=HealthStatus.ERROR,
|
|
@@ -824,7 +934,30 @@ class HealthCheckRunner:
|
|
|
824
934
|
details={"vulnerable_packages": len(issues)},
|
|
825
935
|
)
|
|
826
936
|
|
|
937
|
+
except json.JSONDecodeError as e:
|
|
938
|
+
# Tool output not in expected JSON format
|
|
939
|
+
logger.warning(f"Dependency check JSON parse error ({tool}): {e}")
|
|
940
|
+
return CheckResult(
|
|
941
|
+
category=CheckCategory.DEPS,
|
|
942
|
+
status=HealthStatus.ERROR,
|
|
943
|
+
score=0,
|
|
944
|
+
tool_used=tool,
|
|
945
|
+
details={"error": f"Failed to parse {tool} output: {e}"},
|
|
946
|
+
)
|
|
947
|
+
except subprocess.SubprocessError as e:
|
|
948
|
+
# Tool execution failed
|
|
949
|
+
logger.error(f"Dependency check subprocess error ({tool}): {e}")
|
|
950
|
+
return CheckResult(
|
|
951
|
+
category=CheckCategory.DEPS,
|
|
952
|
+
status=HealthStatus.ERROR,
|
|
953
|
+
score=0,
|
|
954
|
+
tool_used=tool,
|
|
955
|
+
details={"error": f"Failed to run {tool}: {e}"},
|
|
956
|
+
)
|
|
827
957
|
except Exception as e:
|
|
958
|
+
# Unexpected errors - preserve full context for debugging
|
|
959
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional check
|
|
960
|
+
logger.exception(f"Unexpected error in dependency check ({tool}): {e}")
|
|
828
961
|
return CheckResult(
|
|
829
962
|
category=CheckCategory.DEPS,
|
|
830
963
|
status=HealthStatus.ERROR,
|
|
@@ -920,7 +1053,14 @@ class AutoFixer:
|
|
|
920
1053
|
return results
|
|
921
1054
|
|
|
922
1055
|
async def _apply_fix(self, issue: HealthIssue) -> bool:
|
|
923
|
-
"""Apply a single fix.
|
|
1056
|
+
"""Apply a single fix.
|
|
1057
|
+
|
|
1058
|
+
This uses broad exception handling intentionally for graceful degradation.
|
|
1059
|
+
Auto-fixes are optional - the system should continue even if some fixes fail.
|
|
1060
|
+
|
|
1061
|
+
Note:
|
|
1062
|
+
Full exception context is preserved via logger.exception() for debugging.
|
|
1063
|
+
"""
|
|
924
1064
|
if not issue.fix_command:
|
|
925
1065
|
return False
|
|
926
1066
|
|
|
@@ -932,7 +1072,14 @@ class AutoFixer:
|
|
|
932
1072
|
text=True,
|
|
933
1073
|
)
|
|
934
1074
|
return result.returncode == 0
|
|
935
|
-
except
|
|
1075
|
+
except subprocess.SubprocessError as e:
|
|
1076
|
+
# Fix command execution failed
|
|
1077
|
+
logger.error(f"Auto-fix subprocess error for {issue.file_path}: {e}")
|
|
1078
|
+
return False
|
|
1079
|
+
except Exception as e:
|
|
1080
|
+
# Unexpected errors - preserve full context for debugging
|
|
1081
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional auto-fix
|
|
1082
|
+
logger.exception(f"Unexpected error applying fix to {issue.file_path}: {e}")
|
|
936
1083
|
return False
|
|
937
1084
|
|
|
938
1085
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Empathy Framework Configuration Module
|
|
2
|
+
|
|
3
|
+
Provides unified configuration models for agents, wizards, and workflows.
|
|
4
|
+
|
|
5
|
+
Copyright 2025 Smart-AI-Memory
|
|
6
|
+
Licensed under Fair Source License 0.9
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from empathy_llm_toolkit.config.unified import (
|
|
10
|
+
AgentOperationError,
|
|
11
|
+
BookProductionConfig,
|
|
12
|
+
MemDocsConfig,
|
|
13
|
+
ModelTier,
|
|
14
|
+
Provider,
|
|
15
|
+
RedisConfig,
|
|
16
|
+
UnifiedAgentConfig,
|
|
17
|
+
WorkflowMode,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"AgentOperationError",
|
|
22
|
+
"BookProductionConfig",
|
|
23
|
+
"MemDocsConfig",
|
|
24
|
+
"ModelTier",
|
|
25
|
+
"Provider",
|
|
26
|
+
"RedisConfig",
|
|
27
|
+
"UnifiedAgentConfig",
|
|
28
|
+
"WorkflowMode",
|
|
29
|
+
]
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
"""Unified Agent Configuration
|
|
2
|
+
|
|
3
|
+
Single source of truth for all agent, wizard, and workflow configuration.
|
|
4
|
+
Uses Pydantic for validation and type safety.
|
|
5
|
+
|
|
6
|
+
This resolves the AgentConfig duplication between:
|
|
7
|
+
- empathy_llm_toolkit/agent_factory/base.py
|
|
8
|
+
- agents/book_production/base.py
|
|
9
|
+
|
|
10
|
+
Copyright 2025 Smart-AI-Memory
|
|
11
|
+
Licensed under Fair Source License 0.9
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from enum import Enum
|
|
15
|
+
from typing import Any, Literal
|
|
16
|
+
|
|
17
|
+
from pydantic import BaseModel, Field, field_validator
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ModelTier(str, Enum):
|
|
21
|
+
"""Model tier for cost optimization."""
|
|
22
|
+
|
|
23
|
+
CHEAP = "cheap" # Haiku - fast, low cost
|
|
24
|
+
CAPABLE = "capable" # Sonnet - balanced
|
|
25
|
+
PREMIUM = "premium" # Opus - highest quality
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Provider(str, Enum):
|
|
29
|
+
"""LLM provider options."""
|
|
30
|
+
|
|
31
|
+
ANTHROPIC = "anthropic"
|
|
32
|
+
OPENAI = "openai"
|
|
33
|
+
LOCAL = "local"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class WorkflowMode(str, Enum):
|
|
37
|
+
"""Workflow execution modes."""
|
|
38
|
+
|
|
39
|
+
SEQUENTIAL = "sequential"
|
|
40
|
+
PARALLEL = "parallel"
|
|
41
|
+
GRAPH = "graph"
|
|
42
|
+
CONVERSATION = "conversation"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class AgentOperationError(Exception):
|
|
46
|
+
"""Error during agent operation with context."""
|
|
47
|
+
|
|
48
|
+
def __init__(self, operation: str, cause: Exception):
|
|
49
|
+
self.operation = operation
|
|
50
|
+
self.cause = cause
|
|
51
|
+
super().__init__(f"Agent operation '{operation}' failed: {cause}")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class UnifiedAgentConfig(BaseModel):
|
|
55
|
+
"""Unified configuration model for all agents.
|
|
56
|
+
|
|
57
|
+
This is the single source of truth for agent configuration,
|
|
58
|
+
replacing duplicate definitions across the codebase.
|
|
59
|
+
|
|
60
|
+
Example:
|
|
61
|
+
config = UnifiedAgentConfig(
|
|
62
|
+
name="researcher",
|
|
63
|
+
role="researcher",
|
|
64
|
+
model_tier=ModelTier.CAPABLE,
|
|
65
|
+
empathy_level=4
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
# Identity
|
|
71
|
+
name: str = Field(..., min_length=1, description="Unique agent name")
|
|
72
|
+
role: str = Field(default="custom", description="Agent role (researcher, writer, etc.)")
|
|
73
|
+
description: str = Field(default="", description="Agent description")
|
|
74
|
+
|
|
75
|
+
# Model selection
|
|
76
|
+
model_tier: ModelTier = Field(
|
|
77
|
+
default=ModelTier.CAPABLE,
|
|
78
|
+
description="Model tier for cost optimization",
|
|
79
|
+
)
|
|
80
|
+
model_override: str | None = Field(
|
|
81
|
+
default=None,
|
|
82
|
+
description="Specific model ID to use (overrides tier)",
|
|
83
|
+
)
|
|
84
|
+
provider: Provider = Field(default=Provider.ANTHROPIC, description="LLM provider")
|
|
85
|
+
|
|
86
|
+
# Empathy Framework features
|
|
87
|
+
empathy_level: int = Field(
|
|
88
|
+
default=4,
|
|
89
|
+
ge=1,
|
|
90
|
+
le=5,
|
|
91
|
+
description="Empathy level (1=Basic, 4=Anticipatory, 5=Transformative)",
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Feature flags
|
|
95
|
+
memory_enabled: bool = Field(default=True, description="Enable conversation memory")
|
|
96
|
+
pattern_learning: bool = Field(default=True, description="Enable pattern learning")
|
|
97
|
+
cost_tracking: bool = Field(default=True, description="Track API costs")
|
|
98
|
+
use_patterns: bool = Field(default=True, description="Use learned patterns")
|
|
99
|
+
|
|
100
|
+
# LLM parameters
|
|
101
|
+
temperature: float = Field(default=0.7, ge=0.0, le=2.0)
|
|
102
|
+
max_tokens: int = Field(default=4096, ge=1, le=200000)
|
|
103
|
+
timeout: int = Field(default=120, ge=1, description="Timeout in seconds")
|
|
104
|
+
|
|
105
|
+
# Retry configuration
|
|
106
|
+
retry_attempts: int = Field(default=3, ge=0, le=10)
|
|
107
|
+
retry_delay: float = Field(default=1.0, ge=0.0)
|
|
108
|
+
|
|
109
|
+
# System prompt
|
|
110
|
+
system_prompt: str | None = Field(default=None, description="Custom system prompt")
|
|
111
|
+
|
|
112
|
+
# Tools and capabilities
|
|
113
|
+
tools: list[Any] = Field(default_factory=list, description="Agent tools")
|
|
114
|
+
capabilities: list[str] = Field(default_factory=list, description="Agent capabilities")
|
|
115
|
+
|
|
116
|
+
# Framework-specific options
|
|
117
|
+
framework_options: dict[str, Any] = Field(
|
|
118
|
+
default_factory=dict,
|
|
119
|
+
description="Framework-specific configuration",
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
# Extensions
|
|
123
|
+
extra: dict[str, Any] = Field(
|
|
124
|
+
default_factory=dict,
|
|
125
|
+
description="Additional custom configuration",
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
@field_validator("role")
|
|
129
|
+
@classmethod
|
|
130
|
+
def normalize_role(cls, v: str) -> str:
|
|
131
|
+
"""Normalize role to lowercase."""
|
|
132
|
+
return v.lower().strip()
|
|
133
|
+
|
|
134
|
+
def get_model_id(self) -> str:
|
|
135
|
+
"""Get the actual model ID based on tier and provider.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
Model identifier string
|
|
139
|
+
|
|
140
|
+
"""
|
|
141
|
+
if self.model_override:
|
|
142
|
+
return self.model_override
|
|
143
|
+
|
|
144
|
+
# Model mapping by provider and tier
|
|
145
|
+
models = {
|
|
146
|
+
Provider.ANTHROPIC: {
|
|
147
|
+
ModelTier.CHEAP: "claude-3-haiku-20240307",
|
|
148
|
+
ModelTier.CAPABLE: "claude-sonnet-4-20250514",
|
|
149
|
+
ModelTier.PREMIUM: "claude-opus-4-20250514",
|
|
150
|
+
},
|
|
151
|
+
Provider.OPENAI: {
|
|
152
|
+
ModelTier.CHEAP: "gpt-4o-mini",
|
|
153
|
+
ModelTier.CAPABLE: "gpt-4o",
|
|
154
|
+
ModelTier.PREMIUM: "gpt-4o",
|
|
155
|
+
},
|
|
156
|
+
Provider.LOCAL: {
|
|
157
|
+
ModelTier.CHEAP: "llama3.2:3b",
|
|
158
|
+
ModelTier.CAPABLE: "llama3.1:8b",
|
|
159
|
+
ModelTier.PREMIUM: "llama3.1:70b",
|
|
160
|
+
},
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return models.get(self.provider, {}).get(
|
|
164
|
+
self.model_tier,
|
|
165
|
+
"claude-sonnet-4-20250514", # Fallback
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
def for_book_production(self) -> "BookProductionConfig":
|
|
169
|
+
"""Convert to BookProductionConfig for backward compatibility.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
BookProductionConfig instance
|
|
173
|
+
|
|
174
|
+
"""
|
|
175
|
+
return BookProductionConfig(
|
|
176
|
+
agent_config=self,
|
|
177
|
+
memdocs_config=MemDocsConfig(),
|
|
178
|
+
redis_config=RedisConfig(),
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
class Config:
|
|
182
|
+
"""Pydantic configuration."""
|
|
183
|
+
|
|
184
|
+
use_enum_values = True
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class MemDocsConfig(BaseModel):
|
|
188
|
+
"""Configuration for MemDocs pattern storage integration."""
|
|
189
|
+
|
|
190
|
+
enabled: bool = Field(default=True, description="Enable MemDocs integration")
|
|
191
|
+
project: str = Field(default="empathy-framework", description="Project identifier")
|
|
192
|
+
|
|
193
|
+
collections: dict[str, str] = Field(
|
|
194
|
+
default_factory=lambda: {
|
|
195
|
+
"patterns": "learned_patterns",
|
|
196
|
+
"exemplars": "exemplar_examples",
|
|
197
|
+
"transformations": "transformation_examples",
|
|
198
|
+
"feedback": "quality_feedback",
|
|
199
|
+
},
|
|
200
|
+
description="Collection name mappings",
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
# Storage settings
|
|
204
|
+
storage_path: str = Field(default="./patterns", description="Local storage path")
|
|
205
|
+
encryption_enabled: bool = Field(default=False, description="Enable encryption")
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class RedisConfig(BaseModel):
|
|
209
|
+
"""Configuration for Redis state management."""
|
|
210
|
+
|
|
211
|
+
enabled: bool = Field(default=True, description="Enable Redis")
|
|
212
|
+
host: str = Field(default="localhost", description="Redis host")
|
|
213
|
+
port: int = Field(default=6379, ge=1, le=65535)
|
|
214
|
+
db: int = Field(default=0, ge=0, le=15)
|
|
215
|
+
password: str | None = Field(default=None, description="Redis password")
|
|
216
|
+
|
|
217
|
+
prefix: str = Field(default="empathy", description="Key prefix")
|
|
218
|
+
ttl: int = Field(default=86400, ge=0, description="Default TTL in seconds")
|
|
219
|
+
|
|
220
|
+
# Connection pool settings
|
|
221
|
+
max_connections: int = Field(default=10, ge=1)
|
|
222
|
+
socket_timeout: float = Field(default=5.0, ge=0.1)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class BookProductionConfig(BaseModel):
|
|
226
|
+
"""Unified configuration for book production agents.
|
|
227
|
+
|
|
228
|
+
Combines UnifiedAgentConfig with production-specific settings.
|
|
229
|
+
This replaces the duplicate AgentConfig in agents/book_production/base.py.
|
|
230
|
+
"""
|
|
231
|
+
|
|
232
|
+
agent_config: UnifiedAgentConfig
|
|
233
|
+
memdocs_config: MemDocsConfig = Field(default_factory=MemDocsConfig)
|
|
234
|
+
redis_config: RedisConfig = Field(default_factory=RedisConfig)
|
|
235
|
+
|
|
236
|
+
# Book production specific
|
|
237
|
+
chapter_max_words: int = Field(default=5000, ge=100)
|
|
238
|
+
include_code_examples: bool = Field(default=True)
|
|
239
|
+
target_reading_level: Literal["beginner", "intermediate", "advanced"] = "intermediate"
|
|
240
|
+
|
|
241
|
+
@property
|
|
242
|
+
def model(self) -> str:
|
|
243
|
+
"""Get model ID for backward compatibility."""
|
|
244
|
+
return self.agent_config.get_model_id()
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def max_tokens(self) -> int:
|
|
248
|
+
"""Get max tokens for backward compatibility."""
|
|
249
|
+
return self.agent_config.max_tokens
|
|
250
|
+
|
|
251
|
+
@property
|
|
252
|
+
def temperature(self) -> float:
|
|
253
|
+
"""Get temperature for backward compatibility."""
|
|
254
|
+
return self.agent_config.temperature
|
|
255
|
+
|
|
256
|
+
@property
|
|
257
|
+
def timeout(self) -> int:
|
|
258
|
+
"""Get timeout for backward compatibility."""
|
|
259
|
+
return self.agent_config.timeout
|
|
260
|
+
|
|
261
|
+
@property
|
|
262
|
+
def retry_attempts(self) -> int:
|
|
263
|
+
"""Get retry attempts for backward compatibility."""
|
|
264
|
+
return self.agent_config.retry_attempts
|
|
265
|
+
|
|
266
|
+
@property
|
|
267
|
+
def retry_delay(self) -> float:
|
|
268
|
+
"""Get retry delay for backward compatibility."""
|
|
269
|
+
return self.agent_config.retry_delay
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class WorkflowConfig(BaseModel):
|
|
273
|
+
"""Configuration for agent workflows."""
|
|
274
|
+
|
|
275
|
+
name: str = Field(..., min_length=1)
|
|
276
|
+
description: str = Field(default="")
|
|
277
|
+
mode: WorkflowMode = Field(default=WorkflowMode.SEQUENTIAL)
|
|
278
|
+
|
|
279
|
+
# Execution settings
|
|
280
|
+
max_iterations: int = Field(default=10, ge=1, le=100)
|
|
281
|
+
timeout_seconds: int = Field(default=300, ge=1)
|
|
282
|
+
|
|
283
|
+
# State management
|
|
284
|
+
state_schema: dict[str, Any] | None = Field(default=None)
|
|
285
|
+
checkpointing: bool = Field(default=True)
|
|
286
|
+
|
|
287
|
+
# Error handling
|
|
288
|
+
retry_on_error: bool = Field(default=True)
|
|
289
|
+
max_retries: int = Field(default=3, ge=0)
|
|
290
|
+
|
|
291
|
+
# Framework options
|
|
292
|
+
framework_options: dict[str, Any] = Field(default_factory=dict)
|
|
293
|
+
|
|
294
|
+
class Config:
|
|
295
|
+
use_enum_values = True
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Empathy Framework Model Routing
|
|
2
|
+
|
|
3
|
+
Smart routing of tasks to appropriate model tiers for cost optimization:
|
|
4
|
+
- CHEAP tier: Triage, summarization, classification (Haiku/GPT-4o-mini)
|
|
5
|
+
- CAPABLE tier: Code generation, analysis, sub-agent work (Sonnet/GPT-4o)
|
|
6
|
+
- PREMIUM tier: Coordination, synthesis, critical decisions (Opus/o1)
|
|
7
|
+
|
|
8
|
+
Example:
|
|
9
|
+
>>> from empathy_llm_toolkit.routing import ModelRouter
|
|
10
|
+
>>>
|
|
11
|
+
>>> router = ModelRouter()
|
|
12
|
+
>>> model = router.route("summarize", provider="anthropic")
|
|
13
|
+
>>> print(model) # claude-3-5-haiku-20241022
|
|
14
|
+
>>>
|
|
15
|
+
>>> model = router.route("coordinate", provider="anthropic")
|
|
16
|
+
>>> print(model) # claude-opus-4-20250514
|
|
17
|
+
>>>
|
|
18
|
+
>>> cost = router.estimate_cost("fix_bug", input_tokens=5000, output_tokens=1000)
|
|
19
|
+
>>> print(f"Estimated cost: ${cost:.4f}")
|
|
20
|
+
|
|
21
|
+
Copyright 2025 Smart AI Memory, LLC
|
|
22
|
+
Licensed under Fair Source 0.9
|
|
23
|
+
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from .model_router import ModelRouter, ModelTier, TaskRouting
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"ModelRouter",
|
|
30
|
+
"ModelTier",
|
|
31
|
+
"TaskRouting",
|
|
32
|
+
]
|