attune-ai 2.1.4__py3-none-any.whl → 2.1.5__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.
attune/cli/__init__.py CHANGED
@@ -125,7 +125,11 @@ def _register_legacy_commands(subparsers, old_cli):
125
125
  # Import command functions that haven't been extracted yet
126
126
  try:
127
127
  # Patterns commands
128
- from attune.cli import cmd_patterns_export, cmd_patterns_list, cmd_patterns_resolve
128
+ from attune.cli.commands.patterns import (
129
+ cmd_patterns_export,
130
+ cmd_patterns_list,
131
+ cmd_patterns_resolve,
132
+ )
129
133
 
130
134
  patterns_parser = subparsers.add_parser("patterns", help="Pattern management")
131
135
  patterns_sub = patterns_parser.add_subparsers(dest="patterns_command")
attune/cli_legacy.py CHANGED
@@ -83,6 +83,19 @@ try:
83
83
  TELEMETRY_CLI_AVAILABLE = True
84
84
  except ImportError:
85
85
  TELEMETRY_CLI_AVAILABLE = False
86
+ # Define stubs to satisfy type checker - these will never be called
87
+ # because TELEMETRY_CLI_AVAILABLE guards all usages
88
+ cmd_agent_performance = None # type: ignore[assignment]
89
+ cmd_file_test_dashboard = None # type: ignore[assignment]
90
+ cmd_file_test_status = None # type: ignore[assignment]
91
+ cmd_task_routing_report = None # type: ignore[assignment]
92
+ cmd_telemetry_compare = None # type: ignore[assignment]
93
+ cmd_telemetry_export = None # type: ignore[assignment]
94
+ cmd_telemetry_reset = None # type: ignore[assignment]
95
+ cmd_telemetry_savings = None # type: ignore[assignment]
96
+ cmd_telemetry_show = None # type: ignore[assignment]
97
+ cmd_test_status = None # type: ignore[assignment]
98
+ cmd_tier1_status = None # type: ignore[assignment]
86
99
 
87
100
  # Import progressive workflow CLI commands
88
101
  try:
@@ -96,6 +109,12 @@ try:
96
109
  PROGRESSIVE_CLI_AVAILABLE = True
97
110
  except ImportError:
98
111
  PROGRESSIVE_CLI_AVAILABLE = False
112
+ # Define stubs to satisfy type checker - these will never be called
113
+ # because PROGRESSIVE_CLI_AVAILABLE guards all usages
114
+ cmd_analytics = None # type: ignore[assignment]
115
+ cmd_cleanup = None # type: ignore[assignment]
116
+ cmd_list_results = None # type: ignore[assignment]
117
+ cmd_show_report = None # type: ignore[assignment]
99
118
 
100
119
  logger = get_logger(__name__)
101
120
 
@@ -1019,12 +1038,12 @@ def cmd_init(args):
1019
1038
  output_path = args.output or f"attune.config.{config_format}"
1020
1039
 
1021
1040
  # Validate output path to prevent path traversal attacks
1022
- validated_path = _validate_file_path(output_path)
1041
+ validated_path = _validate_file_path(output_path) # type: ignore[misc]
1023
1042
 
1024
1043
  logger.info(f"Initializing new Empathy Framework project with format: {config_format}")
1025
1044
 
1026
1045
  # Create default config
1027
- config = EmpathyConfig()
1046
+ config = EmpathyConfig() # type: ignore[misc]
1028
1047
 
1029
1048
  # Save to file
1030
1049
  if config_format == "yaml":
@@ -1057,7 +1076,7 @@ def cmd_validate(args):
1057
1076
  logger.info(f"Validating configuration file: {filepath}")
1058
1077
 
1059
1078
  try:
1060
- config = load_config(filepath=filepath, use_env=False)
1079
+ config = load_config(filepath=filepath, use_env=False) # type: ignore[misc]
1061
1080
  config.validate()
1062
1081
  logger.info(f"Configuration validation successful: {filepath}")
1063
1082
  logger.info(f"✓ Configuration valid: {filepath}")
@@ -1100,10 +1119,10 @@ def cmd_info(args):
1100
1119
 
1101
1120
  if config_file:
1102
1121
  logger.debug(f"Loading config from file: {config_file}")
1103
- config = load_config(filepath=config_file)
1122
+ config = load_config(filepath=config_file) # type: ignore[misc]
1104
1123
  else:
1105
1124
  logger.debug("Loading default configuration")
1106
- config = load_config()
1125
+ config = load_config() # type: ignore[misc]
1107
1126
 
1108
1127
  logger.info("=== Empathy Framework Info ===\n")
1109
1128
  logger.info("Configuration:")
@@ -1221,7 +1240,7 @@ def cmd_patterns_export(args):
1221
1240
  sys.exit(1)
1222
1241
 
1223
1242
  # Validate output path
1224
- validated_output = _validate_file_path(output_file)
1243
+ validated_output = _validate_file_path(output_file) # type: ignore[misc]
1225
1244
 
1226
1245
  # Save to output format
1227
1246
  try:
@@ -1649,10 +1668,10 @@ def cmd_run(args):
1649
1668
 
1650
1669
  # Load configuration
1651
1670
  if config_file:
1652
- config = load_config(filepath=config_file)
1671
+ config = load_config(filepath=config_file) # type: ignore[misc]
1653
1672
  print(f"✓ Loaded config from: {config_file}")
1654
1673
  else:
1655
- config = EmpathyConfig(user_id=user_id, target_level=level)
1674
+ config = EmpathyConfig(user_id=user_id, target_level=level) # type: ignore[misc]
1656
1675
  print("✓ Using default configuration")
1657
1676
 
1658
1677
  print(f"\nUser ID: {config.user_id}")
@@ -1931,7 +1950,7 @@ def cmd_export(args):
1931
1950
  print(f" Found {len(patterns)} patterns")
1932
1951
 
1933
1952
  # Validate output path
1934
- validated_output = _validate_file_path(output_file)
1953
+ validated_output = _validate_file_path(output_file) # type: ignore[misc]
1935
1954
 
1936
1955
  if format_type == "json":
1937
1956
  # Create filtered library if user_id specified
@@ -2044,7 +2063,7 @@ def cmd_import(args):
2044
2063
  print()
2045
2064
 
2046
2065
 
2047
- def cmd_workflow(args):
2066
+ def cmd_setup(args):
2048
2067
  """Interactive setup workflow.
2049
2068
 
2050
2069
  Guides user through initial framework configuration step by step.
@@ -2163,7 +2182,7 @@ metrics_enabled: {str(config["metrics_enabled"]).lower()}
2163
2182
  llm_provider: "{llm_provider}"
2164
2183
  """
2165
2184
 
2166
- validated_output = _validate_file_path(output_file)
2185
+ validated_output = _validate_file_path(output_file) # type: ignore[misc]
2167
2186
  with open(validated_output, "w") as f:
2168
2187
  f.write(yaml_content)
2169
2188
 
@@ -2272,7 +2291,7 @@ def cmd_provider_set(args):
2272
2291
 
2273
2292
  config["default_provider"] = provider
2274
2293
 
2275
- validated_workflows_path = _validate_file_path(str(workflows_path))
2294
+ validated_workflows_path = _validate_file_path(str(workflows_path)) # type: ignore[misc]
2276
2295
  with open(validated_workflows_path, "w") as f:
2277
2296
  yaml.dump(config, f, default_flow_style=False, sort_keys=False)
2278
2297
 
@@ -2303,7 +2322,7 @@ def cmd_sync_claude(args):
2303
2322
 
2304
2323
  patterns_dir = Path(args.patterns_dir)
2305
2324
  # Validate output directory path
2306
- validated_output_dir = _validate_file_path(args.output_dir)
2325
+ validated_output_dir = _validate_file_path(args.output_dir) # type: ignore[misc]
2307
2326
  output_dir = validated_output_dir
2308
2327
 
2309
2328
  print("=" * 60)
@@ -2341,7 +2360,7 @@ def cmd_sync_claude(args):
2341
2360
  # Write rule file
2342
2361
  rule_file = output_dir / f"{category}.md"
2343
2362
  # Validate rule file path before writing
2344
- validated_rule_file = _validate_file_path(str(rule_file), allowed_dir=str(output_dir))
2363
+ validated_rule_file = _validate_file_path(str(rule_file), allowed_dir=str(output_dir)) # type: ignore[misc]
2345
2364
  with open(validated_rule_file, "w") as f:
2346
2365
  f.write(rule_content)
2347
2366
 
@@ -2806,6 +2825,8 @@ def cmd_workflow(args):
2806
2825
  # Generate or show workflow configuration
2807
2826
  from pathlib import Path
2808
2827
 
2828
+ from attune.workflows.config import WorkflowConfig
2829
+
2809
2830
  config_path = Path(".attune/workflows.yaml")
2810
2831
 
2811
2832
  if config_path.exists() and not getattr(args, "force", False):
@@ -2825,7 +2846,7 @@ def cmd_workflow(args):
2825
2846
 
2826
2847
  # Create config directory and file
2827
2848
  config_path.parent.mkdir(parents=True, exist_ok=True)
2828
- validated_config_path = _validate_file_path(str(config_path))
2849
+ validated_config_path = _validate_file_path(str(config_path)) # type: ignore[misc]
2829
2850
  validated_config_path.write_text(create_example_config())
2830
2851
  print(f"✓ Created workflow config: {validated_config_path}")
2831
2852
  print("\nEdit this file to customize:")
@@ -2889,7 +2910,7 @@ def cmd_frameworks(args):
2889
2910
  )
2890
2911
  else:
2891
2912
  print(f"\nRecommended framework for '{recommend_use_case}': {info['name']}")
2892
- print(f" Best for: {', '.join(info['best_for'])}")
2913
+ print(f" Best for: {', '.join(info['best_for'])}") # type: ignore[arg-type]
2893
2914
  if info.get("install_command"):
2894
2915
  print(f" Install: {info['install_command']}")
2895
2916
  print()
@@ -2945,7 +2966,7 @@ def _cmd_telemetry_show(args):
2945
2966
  if not TELEMETRY_CLI_AVAILABLE:
2946
2967
  print("Telemetry commands not available. Install telemetry dependencies.")
2947
2968
  return 1
2948
- return cmd_telemetry_show(args)
2969
+ return cmd_telemetry_show(args) # type: ignore[misc]
2949
2970
 
2950
2971
 
2951
2972
  def _cmd_telemetry_savings(args):
@@ -2953,7 +2974,7 @@ def _cmd_telemetry_savings(args):
2953
2974
  if not TELEMETRY_CLI_AVAILABLE:
2954
2975
  print("Telemetry commands not available. Install telemetry dependencies.")
2955
2976
  return 1
2956
- return cmd_telemetry_savings(args)
2977
+ return cmd_telemetry_savings(args) # type: ignore[misc]
2957
2978
 
2958
2979
 
2959
2980
  def _cmd_telemetry_compare(args):
@@ -2961,7 +2982,7 @@ def _cmd_telemetry_compare(args):
2961
2982
  if not TELEMETRY_CLI_AVAILABLE:
2962
2983
  print("Telemetry commands not available. Install telemetry dependencies.")
2963
2984
  return 1
2964
- return cmd_telemetry_compare(args)
2985
+ return cmd_telemetry_compare(args) # type: ignore[misc]
2965
2986
 
2966
2987
 
2967
2988
  def _cmd_telemetry_reset(args):
@@ -2969,7 +2990,7 @@ def _cmd_telemetry_reset(args):
2969
2990
  if not TELEMETRY_CLI_AVAILABLE:
2970
2991
  print("Telemetry commands not available. Install telemetry dependencies.")
2971
2992
  return 1
2972
- return cmd_telemetry_reset(args)
2993
+ return cmd_telemetry_reset(args) # type: ignore[misc]
2973
2994
 
2974
2995
 
2975
2996
  def _cmd_telemetry_export(args):
@@ -2977,7 +2998,7 @@ def _cmd_telemetry_export(args):
2977
2998
  if not TELEMETRY_CLI_AVAILABLE:
2978
2999
  print("Telemetry commands not available. Install telemetry dependencies.")
2979
3000
  return 1
2980
- return cmd_telemetry_export(args)
3001
+ return cmd_telemetry_export(args) # type: ignore[misc]
2981
3002
 
2982
3003
 
2983
3004
  def _cmd_tier1_status(args):
@@ -2985,7 +3006,7 @@ def _cmd_tier1_status(args):
2985
3006
  if not TELEMETRY_CLI_AVAILABLE:
2986
3007
  print("Tier 1 monitoring commands not available. Install telemetry dependencies.")
2987
3008
  return 1
2988
- return cmd_tier1_status(args)
3009
+ return cmd_tier1_status(args) # type: ignore[misc]
2989
3010
 
2990
3011
 
2991
3012
  def _cmd_task_routing_report(args):
@@ -2993,7 +3014,7 @@ def _cmd_task_routing_report(args):
2993
3014
  if not TELEMETRY_CLI_AVAILABLE:
2994
3015
  print("Tier 1 monitoring commands not available. Install telemetry dependencies.")
2995
3016
  return 1
2996
- return cmd_task_routing_report(args)
3017
+ return cmd_task_routing_report(args) # type: ignore[misc]
2997
3018
 
2998
3019
 
2999
3020
  def _cmd_test_status(args):
@@ -3001,7 +3022,7 @@ def _cmd_test_status(args):
3001
3022
  if not TELEMETRY_CLI_AVAILABLE:
3002
3023
  print("Tier 1 monitoring commands not available. Install telemetry dependencies.")
3003
3024
  return 1
3004
- return cmd_test_status(args)
3025
+ return cmd_test_status(args) # type: ignore[misc]
3005
3026
 
3006
3027
 
3007
3028
  def _cmd_file_test_status(args):
@@ -3009,7 +3030,7 @@ def _cmd_file_test_status(args):
3009
3030
  if not TELEMETRY_CLI_AVAILABLE:
3010
3031
  print("Tier 1 monitoring commands not available. Install telemetry dependencies.")
3011
3032
  return 1
3012
- return cmd_file_test_status(args)
3033
+ return cmd_file_test_status(args) # type: ignore[misc]
3013
3034
 
3014
3035
 
3015
3036
  def _cmd_file_test_dashboard(args):
@@ -3017,7 +3038,7 @@ def _cmd_file_test_dashboard(args):
3017
3038
  if not TELEMETRY_CLI_AVAILABLE:
3018
3039
  print("Tier 1 monitoring commands not available. Install telemetry dependencies.")
3019
3040
  return 1
3020
- return cmd_file_test_dashboard(args)
3041
+ return cmd_file_test_dashboard(args) # type: ignore[misc]
3021
3042
 
3022
3043
 
3023
3044
  def _cmd_agent_performance(args):
@@ -3025,7 +3046,7 @@ def _cmd_agent_performance(args):
3025
3046
  if not TELEMETRY_CLI_AVAILABLE:
3026
3047
  print("Tier 1 monitoring commands not available. Install telemetry dependencies.")
3027
3048
  return 1
3028
- return cmd_agent_performance(args)
3049
+ return cmd_agent_performance(args) # type: ignore[misc]
3029
3050
 
3030
3051
 
3031
3052
  def main():
@@ -3537,7 +3558,7 @@ def main():
3537
3558
  "--storage-path",
3538
3559
  help="Path to progressive workflow storage (default: .attune/progressive_runs)",
3539
3560
  )
3540
- parser_progressive_list.set_defaults(func=lambda args: cmd_list_results(args))
3561
+ parser_progressive_list.set_defaults(func=lambda args: cmd_list_results(args)) # type: ignore[misc]
3541
3562
 
3542
3563
  # Progressive show command
3543
3564
  parser_progressive_show = progressive_subparsers.add_parser(
@@ -3558,7 +3579,7 @@ def main():
3558
3579
  action="store_true",
3559
3580
  help="Output in JSON format",
3560
3581
  )
3561
- parser_progressive_show.set_defaults(func=lambda args: cmd_show_report(args))
3582
+ parser_progressive_show.set_defaults(func=lambda args: cmd_show_report(args)) # type: ignore[misc]
3562
3583
 
3563
3584
  # Progressive analytics command
3564
3585
  parser_progressive_analytics = progressive_subparsers.add_parser(
@@ -3574,7 +3595,7 @@ def main():
3574
3595
  action="store_true",
3575
3596
  help="Output in JSON format",
3576
3597
  )
3577
- parser_progressive_analytics.set_defaults(func=lambda args: cmd_analytics(args))
3598
+ parser_progressive_analytics.set_defaults(func=lambda args: cmd_analytics(args)) # type: ignore[misc]
3578
3599
 
3579
3600
  # Progressive cleanup command
3580
3601
  parser_progressive_cleanup = progressive_subparsers.add_parser(
@@ -3596,7 +3617,7 @@ def main():
3596
3617
  action="store_true",
3597
3618
  help="Show what would be deleted without actually deleting",
3598
3619
  )
3599
- parser_progressive_cleanup.set_defaults(func=lambda args: cmd_cleanup(args))
3620
+ parser_progressive_cleanup.set_defaults(func=lambda args: cmd_cleanup(args)) # type: ignore[misc]
3600
3621
 
3601
3622
  # Tier 1 automation monitoring commands
3602
3623
 
attune/cli_minimal.py CHANGED
@@ -5,29 +5,29 @@ IMPORTANT: This CLI is for automation only (git hooks, scripts, CI/CD).
5
5
  For interactive use, use Claude Code skills in VSCode or Claude Desktop.
6
6
 
7
7
  Automation commands:
8
- empathy workflow list List available workflows
9
- empathy workflow run <name> Execute a workflow
10
- empathy workflow info <name> Show workflow details
8
+ attune workflow list List available workflows
9
+ attune workflow run <name> Execute a workflow
10
+ attune workflow info <name> Show workflow details
11
11
 
12
12
  Monitoring commands:
13
- empathy dashboard start Start agent coordination dashboard
14
- (opens web UI at http://localhost:8000)
13
+ attune dashboard start Start agent coordination dashboard
14
+ (opens web UI at http://localhost:8000)
15
15
 
16
16
  Utility commands:
17
- empathy telemetry show Display usage summary
18
- empathy telemetry savings Show cost savings
19
- empathy telemetry export Export to CSV/JSON
20
- empathy telemetry routing-stats Show adaptive routing statistics
21
- empathy telemetry routing-check Check for tier upgrade recommendations
22
- empathy telemetry models Show model performance by provider
23
- empathy telemetry agents Show active agents and their status
24
- empathy telemetry signals Show coordination signals for an agent
17
+ attune telemetry show Display usage summary
18
+ attune telemetry savings Show cost savings
19
+ attune telemetry export Export to CSV/JSON
20
+ attune telemetry routing-stats Show adaptive routing statistics
21
+ attune telemetry routing-check Check for tier upgrade recommendations
22
+ attune telemetry models Show model performance by provider
23
+ attune telemetry agents Show active agents and their status
24
+ attune telemetry signals Show coordination signals for an agent
25
25
 
26
- empathy provider show Show current provider config
27
- empathy provider set <name> Set provider (anthropic, openai, hybrid)
26
+ attune provider show Show current provider config
27
+ attune provider set <name> Set provider (anthropic, openai, hybrid)
28
28
 
29
- empathy validate Validate configuration
30
- empathy version Show version
29
+ attune validate Validate configuration
30
+ attune version Show version
31
31
 
32
32
  For interactive development, use Claude Code skills:
33
33
  /dev Developer tools (commit, review, debug, refactor)
@@ -58,7 +58,7 @@ def get_version() -> str:
58
58
  try:
59
59
  from importlib.metadata import version
60
60
 
61
- return version("empathy-framework")
61
+ return version("attune-ai")
62
62
  except Exception: # noqa: BLE001
63
63
  # INTENTIONAL: Fallback for dev installs without metadata
64
64
  return "dev"
@@ -90,7 +90,7 @@ def cmd_workflow_list(args: Namespace) -> int:
90
90
 
91
91
  print("-" * 60)
92
92
  print(f"\nTotal: {len(workflows)} workflows")
93
- print("\nRun a workflow: empathy workflow run <name>")
93
+ print("\nRun a workflow: attune workflow run <name>")
94
94
  return 0
95
95
 
96
96
 
@@ -429,7 +429,7 @@ def cmd_telemetry_routing_stats(args: Namespace) -> int:
429
429
 
430
430
  except ImportError as e:
431
431
  print(f"❌ Adaptive routing not available: {e}")
432
- print(" Ensure empathy-framework is installed with telemetry support")
432
+ print(" Ensure attune-ai is installed with telemetry support")
433
433
  return 1
434
434
  except Exception as e: # noqa: BLE001
435
435
  # INTENTIONAL: CLI commands should catch all errors and report gracefully
@@ -920,7 +920,7 @@ def cmd_validate(args: Namespace) -> int:
920
920
  def cmd_version(args: Namespace) -> int:
921
921
  """Show version information."""
922
922
  version = get_version()
923
- print(f"empathy-framework {version}")
923
+ print(f"attune-ai {version}")
924
924
 
925
925
  if args.verbose:
926
926
  print(f"\nPython: {sys.version}")
@@ -930,7 +930,7 @@ def cmd_version(args: Namespace) -> int:
930
930
  try:
931
931
  from importlib.metadata import requires
932
932
 
933
- reqs = requires("empathy-framework") or []
933
+ reqs = requires("attune-ai") or []
934
934
  print(f"\nDependencies: {len(reqs)}")
935
935
  except Exception: # noqa: BLE001
936
936
  pass
@@ -1104,7 +1104,7 @@ def main(argv: list[str] | None = None) -> int:
1104
1104
  elif args.workflow_command == "run":
1105
1105
  return cmd_workflow_run(args)
1106
1106
  else:
1107
- print("Usage: empathy workflow {list|info|run}")
1107
+ print("Usage: attune workflow {list|info|run}")
1108
1108
  return 1
1109
1109
 
1110
1110
  elif args.command == "telemetry":
@@ -1125,7 +1125,7 @@ def main(argv: list[str] | None = None) -> int:
1125
1125
  elif args.telemetry_command == "signals":
1126
1126
  return cmd_telemetry_signals(args)
1127
1127
  else:
1128
- print("Usage: empathy telemetry {show|savings|export|routing-stats|routing-check|models|agents|signals}")
1128
+ print("Usage: attune telemetry {show|savings|export|routing-stats|routing-check|models|agents|signals}")
1129
1129
  return 1
1130
1130
 
1131
1131
  elif args.command == "provider":
@@ -1134,14 +1134,14 @@ def main(argv: list[str] | None = None) -> int:
1134
1134
  elif args.provider_command == "set":
1135
1135
  return cmd_provider_set(args)
1136
1136
  else:
1137
- print("Usage: empathy provider {show|set}")
1137
+ print("Usage: attune provider {show|set}")
1138
1138
  return 1
1139
1139
 
1140
1140
  elif args.command == "dashboard":
1141
1141
  if args.dashboard_command == "start":
1142
1142
  return cmd_dashboard_start(args)
1143
1143
  else:
1144
- print("Usage: empathy dashboard start [--host HOST] [--port PORT]")
1144
+ print("Usage: attune dashboard start [--host HOST] [--port PORT]")
1145
1145
  return 1
1146
1146
 
1147
1147
  elif args.command == "validate":
attune/core.py CHANGED
@@ -25,6 +25,23 @@ if TYPE_CHECKING:
25
25
  from .pattern_library import PatternLibrary
26
26
 
27
27
 
28
+ @dataclass
29
+ class InteractionResponse:
30
+ """Response from an interaction with EmpathyOS.
31
+
32
+ Attributes:
33
+ level: Empathy level used (1-5)
34
+ response: The response text
35
+ confidence: Confidence score (0.0 to 1.0)
36
+ predictions: Optional list of predictions (for Level 4+)
37
+ """
38
+
39
+ level: int
40
+ response: str
41
+ confidence: float = 1.0
42
+ predictions: list[str] | None = None
43
+
44
+
28
45
  @dataclass
29
46
  class CollaborationState:
30
47
  """Stock & Flow model of AI-human collaboration
@@ -68,6 +85,11 @@ class CollaborationState:
68
85
  # Track trajectory
69
86
  self.trust_trajectory.append(self.trust_level)
70
87
 
88
+ @property
89
+ def current_level(self) -> float:
90
+ """Get current trust level (alias for trust_level)."""
91
+ return self.trust_level
92
+
71
93
 
72
94
  class EmpathyOS:
73
95
  """Empathy Operating System for AI-Human Collaboration.
@@ -130,6 +152,7 @@ class EmpathyOS:
130
152
  shared_library: PatternLibrary | None = None,
131
153
  short_term_memory: RedisShortTermMemory | None = None,
132
154
  access_tier: AccessTier = AccessTier.CONTRIBUTOR,
155
+ persistence_enabled: bool = True,
133
156
  ):
134
157
  """Initialize EmpathyOS
135
158
 
@@ -146,11 +169,13 @@ class EmpathyOS:
146
169
  staging, and conflict resolution.
147
170
  access_tier: Access tier for this agent (Observer, Contributor, Validator, Steward).
148
171
  Determines what operations the agent can perform on shared memory.
172
+ persistence_enabled: Whether to enable pattern/state persistence (default: True)
149
173
 
150
174
  """
151
175
  self.user_id = user_id
152
176
  self.target_level = target_level
153
177
  self.confidence_threshold = confidence_threshold
178
+ self.persistence_enabled = persistence_enabled
154
179
  self.logger = logger or logging.getLogger(__name__)
155
180
  self.shared_library = shared_library
156
181
 
@@ -1263,6 +1288,171 @@ class EmpathyOS:
1263
1288
  """Reset collaboration state (new session)"""
1264
1289
  self.collaboration_state = CollaborationState()
1265
1290
 
1291
+ def interact(
1292
+ self,
1293
+ user_id: str,
1294
+ user_input: str,
1295
+ context: dict | None = None,
1296
+ ) -> InteractionResponse:
1297
+ """Process a user interaction and return a response.
1298
+
1299
+ This is a synchronous convenience method for simple interactions.
1300
+ For full empathy level control, use the level_X_* async methods.
1301
+
1302
+ Args:
1303
+ user_id: User identifier
1304
+ user_input: The user's input text
1305
+ context: Optional context dictionary
1306
+
1307
+ Returns:
1308
+ InteractionResponse with level, response, confidence, and optional predictions
1309
+
1310
+ Example:
1311
+ >>> empathy = EmpathyOS(user_id="dev_123")
1312
+ >>> response = empathy.interact(
1313
+ ... user_id="dev_123",
1314
+ ... user_input="How do I optimize this query?",
1315
+ ... context={"domain": "database"}
1316
+ ... )
1317
+ >>> print(f"[L{response.level}] {response.response}")
1318
+
1319
+ """
1320
+ context = context or {}
1321
+
1322
+ # Determine appropriate empathy level based on trust and context
1323
+ current_trust = self.collaboration_state.trust_level
1324
+ level = self._determine_interaction_level(current_trust, context)
1325
+
1326
+ # Generate response based on level
1327
+ response_text = self._generate_response(user_input, context, level)
1328
+
1329
+ # For Level 4+, generate predictions
1330
+ predictions = None
1331
+ if level >= 4:
1332
+ predictions = self._generate_predictions(user_input, context)
1333
+
1334
+ # Calculate confidence based on context completeness and trust
1335
+ confidence = self._calculate_confidence(context, current_trust)
1336
+
1337
+ # Update interaction tracking
1338
+ self.collaboration_state.total_interactions += 1
1339
+ self.current_empathy_level = level
1340
+
1341
+ return InteractionResponse(
1342
+ level=level,
1343
+ response=response_text,
1344
+ confidence=confidence,
1345
+ predictions=predictions,
1346
+ )
1347
+
1348
+ def record_success(self, success: bool) -> None:
1349
+ """Record the outcome of an interaction for trust tracking.
1350
+
1351
+ Call this after receiving user feedback on whether an interaction
1352
+ was helpful. Updates the collaboration state's trust level.
1353
+
1354
+ Args:
1355
+ success: True if the interaction was helpful, False otherwise
1356
+
1357
+ Example:
1358
+ >>> response = empathy.interact(...)
1359
+ >>> # After getting user feedback
1360
+ >>> feedback = input("Was this helpful? (y/n): ")
1361
+ >>> empathy.record_success(success=(feedback.lower() == 'y'))
1362
+ >>> print(f"Trust level: {empathy.collaboration_state.trust_level:.0%}")
1363
+
1364
+ """
1365
+ outcome = "success" if success else "failure"
1366
+ self.collaboration_state.update_trust(outcome)
1367
+
1368
+ self.logger.debug(
1369
+ f"Recorded interaction outcome: {outcome}",
1370
+ extra={
1371
+ "user_id": self.user_id,
1372
+ "success": success,
1373
+ "new_trust_level": self.collaboration_state.trust_level,
1374
+ },
1375
+ )
1376
+
1377
+ def _determine_interaction_level(self, trust: float, context: dict) -> int:
1378
+ """Determine appropriate empathy level for interaction.
1379
+
1380
+ Args:
1381
+ trust: Current trust level (0.0 to 1.0)
1382
+ context: Interaction context
1383
+
1384
+ Returns:
1385
+ Empathy level (1-5)
1386
+
1387
+ """
1388
+ # Start conservative, increase with trust
1389
+ if trust < 0.3:
1390
+ return 1 # Reactive only
1391
+ elif trust < 0.5:
1392
+ return 2 # Guided
1393
+ elif trust < 0.7:
1394
+ return min(3, self.target_level) # Proactive
1395
+ elif trust < 0.85:
1396
+ return min(4, self.target_level) # Anticipatory
1397
+ else:
1398
+ return min(5, self.target_level) # Systems
1399
+
1400
+ def _generate_response(self, user_input: str, context: dict, level: int) -> str:
1401
+ """Generate response based on empathy level.
1402
+
1403
+ **Extension Point**: Override this method to implement domain-specific
1404
+ response generation (e.g., using LLMs, templates, or rule engines).
1405
+
1406
+ Args:
1407
+ user_input: User's input text
1408
+ context: Interaction context
1409
+ level: Empathy level to use
1410
+
1411
+ Returns:
1412
+ Response text
1413
+
1414
+ """
1415
+ # Default implementation - override for real logic
1416
+ level_descriptions = {
1417
+ 1: "Reactive response",
1418
+ 2: "Guided response with clarification",
1419
+ 3: "Proactive response anticipating needs",
1420
+ 4: "Anticipatory response predicting future needs",
1421
+ 5: "Systems-level response addressing root patterns",
1422
+ }
1423
+ return f"[Level {level}] {level_descriptions.get(level, 'Response')}: Processing '{user_input}'"
1424
+
1425
+ def _generate_predictions(self, user_input: str, context: dict) -> list[str]:
1426
+ """Generate predictions for Level 4+ interactions.
1427
+
1428
+ **Extension Point**: Override to implement domain-specific prediction logic.
1429
+
1430
+ Args:
1431
+ user_input: User's input text
1432
+ context: Interaction context
1433
+
1434
+ Returns:
1435
+ List of prediction strings
1436
+
1437
+ """
1438
+ # Default implementation - override for real predictions
1439
+ return ["Potential follow-up: Related topics may include..."]
1440
+
1441
+ def _calculate_confidence(self, context: dict, trust: float) -> float:
1442
+ """Calculate confidence score for response.
1443
+
1444
+ Args:
1445
+ context: Interaction context
1446
+ trust: Current trust level
1447
+
1448
+ Returns:
1449
+ Confidence score (0.0 to 1.0)
1450
+
1451
+ """
1452
+ # Base confidence on context completeness and trust
1453
+ context_score = min(1.0, len(context) * 0.1) if context else 0.5
1454
+ return (context_score + trust) / 2
1455
+
1266
1456
  # =========================================================================
1267
1457
  # SHORT-TERM MEMORY (Redis-backed Multi-Agent Coordination)
1268
1458
  # =========================================================================
attune/dashboard/app.py CHANGED
@@ -472,7 +472,7 @@ async def websocket_endpoint(websocket: WebSocket):
472
472
  try:
473
473
  while True:
474
474
  # Receive ping to keep connection alive
475
- data = await websocket.receive_text()
475
+ _ = await websocket.receive_text()
476
476
 
477
477
  # Send updates (in production, this would stream from Redis)
478
478
  coordinator = HeartbeatCoordinator()
@@ -41,7 +41,6 @@ from datetime import datetime
41
41
  from pathlib import Path
42
42
  from typing import TYPE_CHECKING, Any
43
43
 
44
- from attune_llm.routing.model_router import ModelRouter, ModelTier
45
44
  from attune.config import _validate_file_path
46
45
  from attune.meta_workflows.agent_creator import DynamicAgentCreator
47
46
  from attune.meta_workflows.form_engine import SocraticFormEngine
@@ -56,6 +55,7 @@ from attune.meta_workflows.models import (
56
55
  from attune.meta_workflows.template_registry import TemplateRegistry
57
56
  from attune.orchestration.agent_templates import get_template
58
57
  from attune.telemetry.usage_tracker import UsageTracker
58
+ from attune_llm.routing.model_router import ModelRouter, ModelTier
59
59
 
60
60
  if TYPE_CHECKING:
61
61
  from attune.meta_workflows.pattern_learner import PatternLearner
@@ -22,6 +22,7 @@ class ProviderMode(str, Enum):
22
22
  """Provider selection mode (Anthropic-only as of v5.0.0)."""
23
23
 
24
24
  SINGLE = "single" # Anthropic for all tiers
25
+ HYBRID = "hybrid" # Deprecated: kept for backward compatibility
25
26
 
26
27
 
27
28
  @dataclass
@@ -150,7 +151,7 @@ class ProviderConfig:
150
151
  if path is None:
151
152
  path = Path.home() / ".empathy" / "provider_config.json"
152
153
  path.parent.mkdir(parents=True, exist_ok=True)
153
- validated_path = _validate_file_path(str(path))
154
+ validated_path = _validate_file_path(str(path)) # type: ignore[misc]
154
155
  with open(validated_path, "w") as f:
155
156
  json.dump(self.to_dict(), f, indent=2)
156
157
 
@@ -280,3 +281,21 @@ def reset_provider_config() -> None:
280
281
  """Reset the global provider configuration (forces reload)."""
281
282
  global _global_config
282
283
  _global_config = None
284
+
285
+
286
+ def configure_hybrid_interactive() -> ProviderConfig:
287
+ """Interactive hybrid provider configuration (DEPRECATED in v5.0.0).
288
+
289
+ Hybrid mode is no longer supported as of v5.0.0 (Claude-native).
290
+ This function now configures Anthropic as the sole provider.
291
+
292
+ Returns:
293
+ ProviderConfig configured for Anthropic
294
+ """
295
+ print("\n" + "=" * 60)
296
+ print("NOTE: Hybrid mode is deprecated (v5.0.0)")
297
+ print("=" * 60)
298
+ print("\nAttune AI is now Claude-native and uses Anthropic exclusively.")
299
+ print("Configuring Anthropic as your provider...\n")
300
+
301
+ return configure_provider_interactive()
attune/telemetry/cli.py CHANGED
@@ -25,6 +25,8 @@ except ImportError:
25
25
 
26
26
  from attune.config import _validate_file_path
27
27
 
28
+ # Import dashboard commands for backward compatibility (re-exported)
29
+ from .commands import cmd_file_test_dashboard, cmd_telemetry_dashboard # noqa: F401
28
30
  from .usage_tracker import UsageTracker
29
31
 
30
32
  # _validate_file_path is now imported from attune.config
@@ -877,8 +877,8 @@ Return ONLY the complete Python test file, no explanations."""
877
877
  CoverageResult with coverage metrics and missing lines
878
878
  """
879
879
  try:
880
- # Run pytest with coverage
881
- result = subprocess.run(
880
+ # Run pytest with coverage (result intentionally unused - we read coverage from file)
881
+ subprocess.run(
882
882
  [
883
883
  sys.executable, "-m", "pytest",
884
884
  str(test_file),
attune/workflows/base.py CHANGED
@@ -255,6 +255,14 @@ class WorkflowResult:
255
255
  # Structured error taxonomy for reliability
256
256
  error_type: str | None = None # "config" | "runtime" | "provider" | "timeout" | "validation"
257
257
  transient: bool = False # True if retry is reasonable (e.g., provider timeout)
258
+ # Optional metadata and summary for extended reporting
259
+ metadata: dict[str, Any] = field(default_factory=dict)
260
+ summary: str | None = None
261
+
262
+ @property
263
+ def duration_seconds(self) -> float:
264
+ """Get duration in seconds (computed from total_duration_ms)."""
265
+ return self.total_duration_ms / 1000.0
258
266
 
259
267
 
260
268
  # Global singleton for workflow history store (lazy-initialized)
@@ -13,9 +13,9 @@ from dataclasses import dataclass
13
13
  from pathlib import Path
14
14
  from typing import Any
15
15
 
16
- from attune_llm.providers import AnthropicBatchProvider
17
16
  from attune.config import _validate_file_path
18
17
  from attune.models import get_model
18
+ from attune_llm.providers import AnthropicBatchProvider
19
19
 
20
20
  logger = logging.getLogger(__name__)
21
21
 
@@ -331,7 +331,7 @@ class TestGeneratorLLM(LLMWorkflowGenerator):
331
331
  Template test file
332
332
  """
333
333
  module_name = context.get("module_name", "unknown")
334
- module_path = context.get("module_path", "unknown")
334
+ # module_path available in context but not used in basic template
335
335
 
336
336
  return f'''"""Behavioral tests for {module_name}.
337
337
 
@@ -120,8 +120,7 @@ class WorkflowReport:
120
120
 
121
121
  def _render_rich(self, console: ConsoleType) -> None:
122
122
  """Render report using Rich."""
123
- # Header with score
124
- header_parts = [f"[bold]{self.title}[/bold]"]
123
+ # Score panel (title shown via score panel)
125
124
  if self.score is not None:
126
125
  score_panel = MetricsPanel.render_score(self.score)
127
126
  console.print(score_panel)
@@ -459,14 +459,13 @@ class ConsoleProgressReporter:
459
459
 
460
460
  # Get current tier from running stage
461
461
  tier_info = ""
462
- model_info = ""
463
462
  if update.current_stage and update.stages:
464
463
  for stage in update.stages:
465
464
  if stage.name == update.current_stage:
466
465
  if stage.status == ProgressStatus.RUNNING:
467
466
  tier_info = f" [{stage.tier.upper()}]"
468
467
  if stage.model:
469
- model_info = f" ({stage.model})"
468
+ tier_info += f" ({stage.model})"
470
469
  # Track stage duration
471
470
  if stage.duration_ms > 0:
472
471
  self._stage_times[stage.name] = stage.duration_ms
@@ -413,8 +413,8 @@ class SEOOptimizationWorkflow(BaseWorkflow):
413
413
  # Note: This method would use the AskUserQuestion tool when called from Claude Code
414
414
  # The actual implementation is handled by the Claude Code agent invoking this workflow
415
415
 
416
- # Discovery question structure for agent to use
417
- discovery_question = {
416
+ # Discovery question structure for agent to use (returned via self._discovery_questions)
417
+ _ = {
418
418
  "question": "What's most important to you right now with your documentation SEO?",
419
419
  "header": "Goal",
420
420
  "multiSelect": False,
@@ -386,7 +386,7 @@ class BehavioralTestGenerationWorkflow(BaseWorkflow):
386
386
  return ModuleInfo(
387
387
  file_path=str(file_path),
388
388
  classes=[asdict(c) for c in analyzer.classes],
389
- functions=[asdict(f) for c in analyzer.functions],
389
+ functions=[asdict(f) for f in analyzer.functions],
390
390
  imports=analyzer.imports,
391
391
  total_lines=len(source_code.splitlines()),
392
392
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: attune-ai
3
- Version: 2.1.4
3
+ Version: 2.1.5
4
4
  Summary: AI collaboration framework with real LLM agent execution, AskUserQuestion tool integration, Socratic agent generation, progressive tier escalation (70-85% cost savings), meta-orchestration, dynamic agent composition (10 patterns including Anthropic-inspired), intelligent caching (85% hit rate), semantic workflow discovery, visual workflow editor, MCP integration for Claude Code, and multi-agent orchestration.
5
5
  Author-email: Patrick Roebuck <admin@smartaimemory.com>
6
6
  Maintainer-email: Smart-AI-Memory <admin@smartaimemory.com>
@@ -2,13 +2,13 @@ attune/__init__.py,sha256=R1re-N0Fi7U3jw6P7FvFYfFZl2KG7qL5eCv54luGs3Y,12045
2
2
  attune/agent_monitoring.py,sha256=s4seLC_J4AtQ3PYWrRPO8YHM-Fbm0Q36kPEdlTHf2HI,13375
3
3
  attune/cache_monitor.py,sha256=lcBqODhYY9iPaH35PWkOSgyMavdvXneHv9F57dPmjnc,11190
4
4
  attune/cache_stats.py,sha256=yZvjC-lCN7rBBeUX6-HG5g5IeCOUZy-Euqu_ey1FLKY,10228
5
- attune/cli_legacy.py,sha256=8ZfHp50jaPs9hZ3YErBTNRpSsvRIvwwMKEmMvgDU7eQ,140079
6
- attune/cli_minimal.py,sha256=pq12dPwoI4MWL4UxrrOtRDMhb5diNb2czfxDVZjTLJo,41091
5
+ attune/cli_legacy.py,sha256=1KO8MPJWSroV6vGyW6uDZ8Iv5CCG_WLInC0a1yfJ2JU,141930
6
+ attune/cli_minimal.py,sha256=MbhXsPie6VlLds4ZXsP5pp1-sQXxs-LVparKQlq0YFQ,41037
7
7
  attune/cli_router.py,sha256=iKbf3Ayb5Z5qCfAajUr8b1Y4AZcwpLBYaCEug3OqTkI,16106
8
8
  attune/cli_unified.py,sha256=PgfCbV5Cb-mKBbS4lLMpaO3m7OWUOniK9M3R6V2R1Dg,25241
9
9
  attune/config.py,sha256=eocyHkwf85r0EfQYzeskxZkDzEK-wrjGNMBL2ccsUs0,16710
10
10
  attune/coordination.py,sha256=gsU2ZiEpjnicV9frq9QNo0zGxf5yQ7n68SvbhnernDM,28501
11
- attune/core.py,sha256=Z_fX85B42J3R7-JkTlFU4A-gFeo-nPrSBmUr9mh2_QU,53956
11
+ attune/core.py,sha256=U_n6CN-YfLDCPVPdlR1DDcUsz_225CryJ6wGZpHivpY,60469
12
12
  attune/cost_tracker.py,sha256=i6K2CR2CHlRMJlrvkYCumdEA9X_XR6_MrNCEGzVJcDg,22977
13
13
  attune/discovery.py,sha256=cRlxExSxAlUXd8AKuzb0_KglWCPrdqPFfeYsR7bOd1s,9936
14
14
  attune/emergence.py,sha256=uMNcB3npENNEharvgXAaRazXLMn5fsKtp-p-PFzhyi8,11361
@@ -38,7 +38,7 @@ attune/cache/dependency_manager.py,sha256=5syHCeunxJHBFggjcMMNSvJw4EJfICfW2mmayA
38
38
  attune/cache/hash_only.py,sha256=N9fJw-IGOzgfDOuKe15e3AzLrxkjDBbwDXEgR1DYXAo,7492
39
39
  attune/cache/hybrid.py,sha256=S73yjzbSeUi_PtE-hEWtml9CN-V3W8qzAlIGu5Y17K0,15541
40
40
  attune/cache/storage.py,sha256=-ODkX61DqbK-eDC0uUeRtjcxfKYwK4PxG7mou4x6vgU,7787
41
- attune/cli/__init__.py,sha256=kb3erHBlW0Esb24HhfJ0pnu2x-B4OBp9w0pTtVUwUQ0,4922
41
+ attune/cli/__init__.py,sha256=Zwr9Zmk82WKPqtx57nvt9mlA9InQIkmrpsK4neJl9Ag,4989
42
42
  attune/cli/__main__.py,sha256=3j6xfa_jrrXAXK7zp0AaKAgG224VxJfrpu-iUmmUkY0,211
43
43
  attune/cli/core.py,sha256=YXGwU5nokchAgSSt22VBcK7W8wF0qa-AEgbmxn4mwMA,875
44
44
  attune/cli/commands/__init__.py,sha256=GYdoNv80KS2p7bCThuoRbhiLmIZW6ddPqPEFEx567nQ,35
@@ -84,7 +84,7 @@ attune/config/__init__.py,sha256=HQDPMUqEgGrJvprhtydEYdNzSoVFmVGgzgTtoWRnta8,169
84
84
  attune/config/xml_config.py,sha256=he7wvXaHgX0a8NhcexG5eyGXtkeCtoeA3lqPHfzXlPw,8892
85
85
  attune/core_modules/__init__.py,sha256=jUbjfT2UHOLrJStqvIPqxbr02_2fofqTYqGdXvKxwFI,274
86
86
  attune/dashboard/__init__.py,sha256=8H09R2SEyNaspr04Ln3wahisttc5U-gkvKoibIcmNm4,1400
87
- attune/dashboard/app.py,sha256=TYArbaqtiWzQdDZUNJAoHtdSjMZ-F4uSCPMyLMUgzDI,16139
87
+ attune/dashboard/app.py,sha256=D1GBqLwNWMn4onUVHNe1JSHDB_Vn8G05yJ-nA6_4b3Y,16136
88
88
  attune/dashboard/simple_server.py,sha256=z9R6swMiP9dI_DVjMjdRYa8_hJE-C2nqgLOSRXrd9Rk,16058
89
89
  attune/dashboard/standalone_server.py,sha256=-hvcidx-sA4tOy4K8MPCzcazNOzmp2oXQdMBL8mPZ9g,20854
90
90
  attune/hot_reload/README.md,sha256=rPQloTKrb_SBdeA48fZm-ry2X-BCrTEc2bET7_OWptk,10397
@@ -140,7 +140,7 @@ attune/meta_workflows/pattern_learner.py,sha256=VoJe_1PYFZK4_9UK_YKZ5vR-6DWUUouq
140
140
  attune/meta_workflows/plan_generator.py,sha256=Wtb-JphXd_lJDFeOjRdxMzgnecDrsA3pjo7hF-IgFLU,11232
141
141
  attune/meta_workflows/session_context.py,sha256=U1LZQO4Fl-jm6Q14FF85oPeYfkwVl15ajq70xyo4Rgw,12330
142
142
  attune/meta_workflows/template_registry.py,sha256=HBehRIzKAH1weN5BQ69WLCwoxf1FwZYVIWH6qNP1huo,7476
143
- attune/meta_workflows/workflow.py,sha256=wJg5md3QtgyyscyAEDYMZY3nCLo802MiJPYhCTvCDUo,35964
143
+ attune/meta_workflows/workflow.py,sha256=VYvyqlu46Ft8VkfGh0dCktFWMB7vnVxCwDE3S2gbM2M,35964
144
144
  attune/meta_workflows/cli_commands/__init__.py,sha256=qWdPRbusNXlrMPZNV-laXqxkT-o7hzNqhoam1OxMCag,1505
145
145
  attune/meta_workflows/cli_commands/agent_commands.py,sha256=9TQORpj0MLu35GgQXVooE3UNYFd-oE68YbHy8l9o9hs,11296
146
146
  attune/meta_workflows/cli_commands/analytics_commands.py,sha256=c-bTkxyjyi8E48xQNnJ7ZABOqFMJNS4oj6Ui_zRw6WM,14448
@@ -160,7 +160,7 @@ attune/models/cli.py,sha256=c54oqbjDoeQCrA6C1wy6OlyKTfJFLyjZx2Nf8SFekNY,22188
160
160
  attune/models/empathy_executor.py,sha256=szK2VgJ0pKt-fiNvoRrnBF4gV1qOetvjbhmUjAHBIhc,12687
161
161
  attune/models/executor.py,sha256=TLJixpVfbt-Xbl9lCPIaGg0UJe1m9wHaEOezLtjtQJU,7475
162
162
  attune/models/fallback.py,sha256=-wX0vabHxqriR1IUYVdsHTxJm56kXUgO81IEvgmngCQ,25804
163
- attune/models/provider_config.py,sha256=rQBTQJwg_35IHwVbxT8mM72bV2LXTf08PITugr3fDHo,9220
163
+ attune/models/provider_config.py,sha256=_1XnaPQjnngOkeO48RlgST7yZHTOZuics_rpmjq-Bdc,9926
164
164
  attune/models/registry.py,sha256=JSwt6Sv8AQD4Y9cZbz6viAIiTDiwFDYW6BDE_NO9wBI,15538
165
165
  attune/models/tasks.py,sha256=bVbxYXuf6OyyW-R5l68rSmtm80YBNpPaf3N79nXq_Gg,10383
166
166
  attune/models/token_estimator.py,sha256=9egCxtPykq9sb-N2EMyE0u25zDhtcZWxlHHnB-QSErs,13466
@@ -245,7 +245,7 @@ attune/telemetry/__init__.py,sha256=DpNi4Eglyj7mAA4XT3GFpidnvvbVNC7Qo1Te9Q5wQ44,
245
245
  attune/telemetry/agent_coordination.py,sha256=oQHnKZO_ia2hogyMTlg18hPgkSgWnFtB9J-WexSjKno,15834
246
246
  attune/telemetry/agent_tracking.py,sha256=PZo_jHm2VQKlTVxnhEnz5GfaABHwuZY4Bb0E50vOTeU,12312
247
247
  attune/telemetry/approval_gates.py,sha256=M7tJdpg0ygkmOx9HkQ19tCfexnMe23mZ2N1PQchuP5k,19068
248
- attune/telemetry/cli.py,sha256=ex8bl1ZEGiETOD6oqCcz6PVV10VoKxFI-Oe06Z_-Nm0,45500
248
+ attune/telemetry/cli.py,sha256=peqkbVW0kC2KiXqyl8URWK15Z2pXxbKvy_DbN9izgQ0,45654
249
249
  attune/telemetry/event_streaming.py,sha256=sl8m0g3stTQJQNyuoX5ec-zNoh0oro0vGe6Q6mTR-zc,13393
250
250
  attune/telemetry/feedback_loop.py,sha256=ikvqxy4CnYdsFpizMEn7hypRaAQsubflOyDDuHpjhK0,20054
251
251
  attune/telemetry/usage_tracker.py,sha256=drUOWJ3R3MkYGF73fLYwZtQJYvJCbahc4-kpgVKzlCE,21182
@@ -268,9 +268,9 @@ attune/workflow_patterns/output.py,sha256=EyioUYeXGQWllZdJXHXv2mLwl7fMwihrEb8D1S
268
268
  attune/workflow_patterns/registry.py,sha256=0U_XT0hdQ5fLHuEJlrvzjaCBUyeWDA675_hEyvHxT0o,7461
269
269
  attune/workflow_patterns/structural.py,sha256=zAm5n1ifngAWiVasulljEeTkWgrrvYrd7kEFfTwXpqo,9423
270
270
  attune/workflows/__init__.py,sha256=kUEbqKuby0qIikiBPmK5HCkBn1N3sSXkD3_L9UUu070,20359
271
- attune/workflows/autonomous_test_gen.py,sha256=PTQGlX1K1WJhkT9uwv0S7ybo10VGRofxlIYzeISjCM0,47444
272
- attune/workflows/base.py,sha256=SKsQWxAWRQ046P0Db3sLN2U5bFKHA39SWt2J0c271uI,99410
273
- attune/workflows/batch_processing.py,sha256=fhvACf8gIZ6sUSZtqOtITzSHuxggnFfQ6aS0GbthGlU,11583
271
+ attune/workflows/autonomous_test_gen.py,sha256=6Ip6N8bFgUN3SDF8qWSiljqwHmEPks7dl-mKwLTmD5I,47494
272
+ attune/workflows/base.py,sha256=lvTjVc5MJjPAaSkM7sWYeL1RET8eoWWeRDiKhyCjBeM,99735
273
+ attune/workflows/batch_processing.py,sha256=QcPREUV6D9gIJICkjMh09vmJ-1dtfRSIqCLsT4lT9bM,11583
274
274
  attune/workflows/bug_predict.py,sha256=N5AjEQ-eJJH69tTqlEyQ2khPXR6IlleOLwJI9gDZVkY,40464
275
275
  attune/workflows/builder.py,sha256=gaPPFoiToSx3EznCWV-iBc7wQef3F1ODs0kGjjb2esc,8603
276
276
  attune/workflows/caching.py,sha256=SnFyEZJCVpe_ijGldW2MRjzNL-Hd8Fj8Sbb2HiuxqT8,8126
@@ -283,7 +283,7 @@ attune/workflows/document_manager.py,sha256=z_r7g2iFXgyxDZebbVJ3ArbYi8FNvJip-Sux
283
283
  attune/workflows/document_manager_README.md,sha256=4vAQ3-ENB2mxc_68dosG-cwAf8W8DWzHtOpaUzRWZKA,2145
284
284
  attune/workflows/documentation_orchestrator.py,sha256=Pfs7nUKSsGYIjkVgOaTx3Ethu42FjdEftxAVcGUVKEo,43007
285
285
  attune/workflows/history.py,sha256=80f2Ltvbs5MBbps4hp8JBBa7H7t-pd8z6YsA7SwE8xU,16463
286
- attune/workflows/llm_base.py,sha256=VhKjXUVuDD_QdWKTN89R-owd4RkwqYsh7WcqYsnhMjo,10777
286
+ attune/workflows/llm_base.py,sha256=-gNCvt_WMgeCkWCEp6jx_f57zn2MVgesNXmYy6J5MGI,10791
287
287
  attune/workflows/manage_docs.py,sha256=W58FjauO2K7v6KENqF80txor-VX5f5S9py2HKfXtTh8,2123
288
288
  attune/workflows/manage_docs_README.md,sha256=7ouxAkpcGVqBF_O8VKJGeANvP0jl5r0Zm0TwZyIsKEk,1903
289
289
  attune/workflows/manage_documentation.py,sha256=TK1odUk_79cMj0AKGBjJ9Z_3n5oCOARj2MQ3lQgdKcQ,30068
@@ -291,10 +291,10 @@ attune/workflows/new_sample_workflow1.py,sha256=BRux1_UdG1MJRlsQvWQAr6Qocq_N2G5p
291
291
  attune/workflows/new_sample_workflow1_README.md,sha256=1pd--DASCiZlqMmcaq-FI_zIaGonNxd-4S6wZDnbMMk,2362
292
292
  attune/workflows/orchestrated_health_check.py,sha256=d4R8iOvw4kQ_EfRdvNYDNrjjR6hzPow55fWSuLHkhPs,30486
293
293
  attune/workflows/orchestrated_release_prep.py,sha256=Erp2rw-EBNOfIwyT0nJhGqpYPg2v-YL_h06aMtaALlA,20224
294
- attune/workflows/output.py,sha256=BJHDdaYB7ptemZy8KHbuLkSmrEAiFCArjOfvQfRMnCU,12829
294
+ attune/workflows/output.py,sha256=AASe1CexsgnMGvWOH2yGYDqooZX-nZFvno4bmzHKgqg,12799
295
295
  attune/workflows/perf_audit.py,sha256=Xjom8vg4W9vQ4DKQTVTnhNzsccOD0RyIcAN2YwPocdI,32203
296
296
  attune/workflows/pr_review.py,sha256=lR7TxvGjBj1fIMxYgBtgxuSvWFTGqQHTsVpL5zKLUB8,26796
297
- attune/workflows/progress.py,sha256=z_0UV2uH4Xu9fG85VYtcqJwJWQhTfa7WvFqrtIe-ISE,26588
297
+ attune/workflows/progress.py,sha256=JcPlfvGw2Nj4YZIyF3JbjiotM1bPJRMHLQXQdNt2JY0,26564
298
298
  attune/workflows/progress_server.py,sha256=3UmIW8j-Hxayod4kV9BoWPvJO8lNX38YVCq6UDEnYlQ,10229
299
299
  attune/workflows/refactor_plan.py,sha256=mp8AHxS5bbH-B-SEJDkukh07xCISUjBBiSjecvLyf-8,25591
300
300
  attune/workflows/release_prep.py,sha256=itcZWMqnhHeo4vVdXQa6Aqo054SqdoVnMlTCtdNnxfE,31078
@@ -305,14 +305,14 @@ attune/workflows/secure_release.py,sha256=cMhTT-iF_pTu9oS08QpWJBg15-Azx7AVA_ucRH
305
305
  attune/workflows/security_adapters.py,sha256=VZNBvUMI2U4KfC84rELYAKxlL5Xi_xYUlFLDKRVveNc,10918
306
306
  attune/workflows/security_audit.py,sha256=kPNoQ78q1B5ieNWW2wTedNiF-JZztaU4N3oEN_snlvU,52438
307
307
  attune/workflows/security_audit_phase3.py,sha256=fVNeqTVqyJblYyflKikAFvq24qgd6owKiMZKvvqlZuI,11534
308
- attune/workflows/seo_optimization.py,sha256=X8hg8qhIkqPazDcbYh7k_hyxze6aEk-nczVFckwMmnM,23257
308
+ attune/workflows/seo_optimization.py,sha256=rt9RO_yS0GVpfT02P5Sj7YNjFDnY2hKzG4FMM9CNf-s,23281
309
309
  attune/workflows/step_config.py,sha256=aytYrjGjY-7GaC0YNmQGJhelCrhj2CjwZg5DxsH1RaE,7197
310
310
  attune/workflows/telemetry_mixin.py,sha256=hymB5I_-d6UC7fhMgkhdFWLAr8Nczr2yR1k44j-aJtc,10071
311
311
  attune/workflows/test5.py,sha256=LGUrTScjgSx9bq9JhNt8ykJ16dZFUaOiH6rvgaNxs4c,3754
312
312
  attune/workflows/test5_README.md,sha256=SgqhotqO--Mn7kdRcCXpiS1HW-kRCjFih6pjq5qDmNM,2402
313
313
  attune/workflows/test_coverage_boost_crew.py,sha256=YQsqrDHknTlrrBTz8nsAiYYlwCdMeUpm5SicL4q8bl4,31041
314
314
  attune/workflows/test_gen.py,sha256=3zshDv6xCXg1NIkqhMhxzxq7UvY4EYdkhAVxn6caLME,1311
315
- attune/workflows/test_gen_behavioral.py,sha256=9nJPZI66iL-P16_xDhptGLJs70WTbBQi8uOKr3VkTko,15759
315
+ attune/workflows/test_gen_behavioral.py,sha256=zWKhQj8Yibj7IZSKjnXfN1doRhm7T6cKYUuKGSyYFxo,15759
316
316
  attune/workflows/test_gen_parallel.py,sha256=DmpaJoRaOD94tMT0_IShBui62cBS0OJvyafR_2wSzUk,12134
317
317
  attune/workflows/test_lifecycle.py,sha256=rgLaO_WMU5IQBYcZVKGJSQUd2RCOlKA07F9harL0T3A,16886
318
318
  attune/workflows/test_maintenance.py,sha256=x4uObZo6ysFwM-gzsxcNZ5WSLULX2nFS5MlMdzWRWxs,22946
@@ -347,8 +347,8 @@ attune/workflows/test_gen/data_models.py,sha256=wXfef60ptiG6AvygayTxWqlL5FVOss19
347
347
  attune/workflows/test_gen/report_formatter.py,sha256=RaxbDp6-9iQRfJmVwrrIReVkOkrnb668NgHrNaS-SPY,10705
348
348
  attune/workflows/test_gen/test_templates.py,sha256=4ywqGYYaSoZxOU6Y1_E-27KEgMI5-v2a1ndia406E9c,13180
349
349
  attune/workflows/test_gen/workflow.py,sha256=U0dhAcCKmlltPIvCSXUeFzt_Q4TodQI4tXtR6cz19MQ,25729
350
- attune_ai-2.1.4.dist-info/licenses/LICENSE,sha256=kqe3EeGatNB79lUTHxjLnxDe7VJr0iYetThOr4_Fx7A,11348
351
- attune_ai-2.1.4.dist-info/licenses/LICENSE_CHANGE_ANNOUNCEMENT.md,sha256=JH9yAQGv_lQej5YlztI_kawbVQ2H8uVLhPGlrWnR_34,3844
350
+ attune_ai-2.1.5.dist-info/licenses/LICENSE,sha256=kqe3EeGatNB79lUTHxjLnxDe7VJr0iYetThOr4_Fx7A,11348
351
+ attune_ai-2.1.5.dist-info/licenses/LICENSE_CHANGE_ANNOUNCEMENT.md,sha256=JH9yAQGv_lQej5YlztI_kawbVQ2H8uVLhPGlrWnR_34,3844
352
352
  attune_healthcare/__init__.py,sha256=4NioL1_86UXzkd-QNkQZUSZ8rKTQGSP0TC9VXP32kQs,295
353
353
  attune_healthcare/monitors/__init__.py,sha256=Udp8qfZR504QAq5_eQjvtIaE7v06Yguc7nuF40KllQc,196
354
354
  attune_healthcare/monitors/clinical_protocol_monitor.py,sha256=MWE5t8tW9HWZn_SNo-inx8-0nhdTNGhbcB8ZeDWyXa0,11648
@@ -450,8 +450,8 @@ workflow_scaffolding/__init__.py,sha256=UpX5vjjjPjIaAKyIV1D4GxJzLUZy5DzdzgSkePYM
450
450
  workflow_scaffolding/__main__.py,sha256=0qspuNoadTDqyskXTlT8Sahqau-XIxN35NHTSGVW6z4,236
451
451
  workflow_scaffolding/cli.py,sha256=RUVqU9SeAgm7YkM0YNd-quh8u6BNzmX8xM2y9K_p68Y,6759
452
452
  workflow_scaffolding/generator.py,sha256=2WC02A10lzF2NQgOn66ksV17Oe72kKlU2qCQs39LIlw,8861
453
- attune_ai-2.1.4.dist-info/METADATA,sha256=GxzUd0l3D9p-ExI5H4sg6hsMVbvbLBQZSszVlgjxWoI,33764
454
- attune_ai-2.1.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
455
- attune_ai-2.1.4.dist-info/entry_points.txt,sha256=GVlb04zFlpkaPtaL7X3JCZI8R0AEOZRsZjJ-wIDQvdo,1458
456
- attune_ai-2.1.4.dist-info/top_level.txt,sha256=iLyjKpuOzWtwmIOZqzeBh8_SVztY2vFvhHcyo1WPtTY,73
457
- attune_ai-2.1.4.dist-info/RECORD,,
453
+ attune_ai-2.1.5.dist-info/METADATA,sha256=Qhr3gltp2pkZU4ahaBWXr9uGcM14d3vNUmDoYYm13Oo,33764
454
+ attune_ai-2.1.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
455
+ attune_ai-2.1.5.dist-info/entry_points.txt,sha256=GVlb04zFlpkaPtaL7X3JCZI8R0AEOZRsZjJ-wIDQvdo,1458
456
+ attune_ai-2.1.5.dist-info/top_level.txt,sha256=iLyjKpuOzWtwmIOZqzeBh8_SVztY2vFvhHcyo1WPtTY,73
457
+ attune_ai-2.1.5.dist-info/RECORD,,