attune-ai 2.1.3__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 +7 -3
- attune/cli/commands/profiling.py +1 -1
- attune/cli/commands/utilities.py +1 -1
- attune/cli/core.py +1 -1
- attune/cli_legacy.py +52 -31
- attune/cli_minimal.py +29 -29
- attune/core.py +190 -0
- attune/dashboard/app.py +1 -1
- attune/meta_workflows/workflow.py +1 -1
- attune/models/provider_config.py +20 -1
- attune/telemetry/cli.py +2 -0
- attune/workflows/autonomous_test_gen.py +2 -2
- attune/workflows/base.py +8 -0
- attune/workflows/batch_processing.py +1 -1
- attune/workflows/llm_base.py +1 -1
- attune/workflows/output.py +1 -2
- attune/workflows/progress.py +1 -2
- attune/workflows/seo_optimization.py +2 -2
- attune/workflows/test_gen_behavioral.py +1 -1
- {attune_ai-2.1.3.dist-info → attune_ai-2.1.5.dist-info}/METADATA +1 -1
- {attune_ai-2.1.3.dist-info → attune_ai-2.1.5.dist-info}/RECORD +26 -26
- {attune_ai-2.1.3.dist-info → attune_ai-2.1.5.dist-info}/WHEEL +0 -0
- {attune_ai-2.1.3.dist-info → attune_ai-2.1.5.dist-info}/entry_points.txt +0 -0
- {attune_ai-2.1.3.dist-info → attune_ai-2.1.5.dist-info}/licenses/LICENSE +0 -0
- {attune_ai-2.1.3.dist-info → attune_ai-2.1.5.dist-info}/licenses/LICENSE_CHANGE_ANNOUNCEMENT.md +0 -0
- {attune_ai-2.1.3.dist-info → attune_ai-2.1.5.dist-info}/top_level.txt +0 -0
attune/cli/__init__.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Attune AI CLI - Refactored modular structure.
|
|
2
2
|
|
|
3
|
-
Entry point for the
|
|
3
|
+
Entry point for the attune command-line interface.
|
|
4
4
|
|
|
5
5
|
Copyright 2025 Smart-AI-Memory
|
|
6
6
|
Licensed under Fair Source License 0.9
|
|
@@ -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
|
|
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/commands/profiling.py
CHANGED
attune/cli/commands/utilities.py
CHANGED
attune/cli/core.py
CHANGED
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
|
|
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
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
2
|
+
"""Attune AI CLI.
|
|
3
3
|
|
|
4
4
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
14
|
-
|
|
13
|
+
attune dashboard start Start agent coordination dashboard
|
|
14
|
+
(opens web UI at http://localhost:8000)
|
|
15
15
|
|
|
16
16
|
Utility commands:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
27
|
-
|
|
26
|
+
attune provider show Show current provider config
|
|
27
|
+
attune provider set <name> Set provider (anthropic, openai, hybrid)
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
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("
|
|
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:
|
|
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
|
|
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"
|
|
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("
|
|
933
|
+
reqs = requires("attune-ai") or []
|
|
934
934
|
print(f"\nDependencies: {len(reqs)}")
|
|
935
935
|
except Exception: # noqa: BLE001
|
|
936
936
|
pass
|
|
@@ -948,8 +948,8 @@ def cmd_version(args: Namespace) -> int:
|
|
|
948
948
|
def create_parser() -> argparse.ArgumentParser:
|
|
949
949
|
"""Create the argument parser."""
|
|
950
950
|
parser = argparse.ArgumentParser(
|
|
951
|
-
prog="
|
|
952
|
-
description="
|
|
951
|
+
prog="attune",
|
|
952
|
+
description="Attune AI CLI (automation interface - for git hooks, scripts, CI/CD)",
|
|
953
953
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
954
954
|
epilog="""
|
|
955
955
|
NOTE: This CLI is for automation only. For interactive development,
|
|
@@ -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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
attune/models/provider_config.py
CHANGED
|
@@ -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
|
-
|
|
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
|
|
attune/workflows/llm_base.py
CHANGED
|
@@ -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
|
|
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
|
|
attune/workflows/output.py
CHANGED
|
@@ -120,8 +120,7 @@ class WorkflowReport:
|
|
|
120
120
|
|
|
121
121
|
def _render_rich(self, console: ConsoleType) -> None:
|
|
122
122
|
"""Render report using Rich."""
|
|
123
|
-
#
|
|
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)
|
attune/workflows/progress.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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=
|
|
6
|
-
attune/cli_minimal.py,sha256=
|
|
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=
|
|
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,9 +38,9 @@ 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=
|
|
41
|
+
attune/cli/__init__.py,sha256=Zwr9Zmk82WKPqtx57nvt9mlA9InQIkmrpsK4neJl9Ag,4989
|
|
42
42
|
attune/cli/__main__.py,sha256=3j6xfa_jrrXAXK7zp0AaKAgG224VxJfrpu-iUmmUkY0,211
|
|
43
|
-
attune/cli/core.py,sha256=
|
|
43
|
+
attune/cli/core.py,sha256=YXGwU5nokchAgSSt22VBcK7W8wF0qa-AEgbmxn4mwMA,875
|
|
44
44
|
attune/cli/commands/__init__.py,sha256=GYdoNv80KS2p7bCThuoRbhiLmIZW6ddPqPEFEx567nQ,35
|
|
45
45
|
attune/cli/commands/batch.py,sha256=0TQ50VuFILN6ZTS-JrdtQi7ibuVwEUPq8xkdFsRU5_k,8562
|
|
46
46
|
attune/cli/commands/cache.py,sha256=79DF06zQ7Noe7WwOLtqbDVIngpXCLkjNltP-R7t18iE,8176
|
|
@@ -52,14 +52,14 @@ attune/cli/commands/memory.py,sha256=566vPYCyqoS3231nhqCr2vDUQYCBtP3NT8iLj1-30mQ
|
|
|
52
52
|
attune/cli/commands/metrics.py,sha256=v4KW46UWYOysCFQVLE2kqISil1YsHARbs9kE0mp_RvQ,3164
|
|
53
53
|
attune/cli/commands/orchestrate.py,sha256=pGJRschCayD2E2wimTG4zXYQxEA1Kk7g_sMQFdeXM48,6541
|
|
54
54
|
attune/cli/commands/patterns.py,sha256=-f6ZDrUIupZPmdjM87qitxRpBYMns1KFyiC9okq14vI,7917
|
|
55
|
-
attune/cli/commands/profiling.py,sha256=
|
|
55
|
+
attune/cli/commands/profiling.py,sha256=Q6JY2Ui7mfOyT4hVtpzTi0ZlpCCW7HWTX4SrcVfhIGY,6009
|
|
56
56
|
attune/cli/commands/provider.py,sha256=o1vDEIxjE6qhpFl__yx2qeiMOqkR2zDUlrCdkcrEANs,3077
|
|
57
57
|
attune/cli/commands/routing.py,sha256=BwuGBVKQ4S7szQW4ubce9pO5uLaxEoHHlpR7Uljcf5I,9896
|
|
58
58
|
attune/cli/commands/setup.py,sha256=0mS_ya2hQ3ZEQH9CYoozBoVWErVr-5aQ76G8NEPqXu8,3447
|
|
59
59
|
attune/cli/commands/status.py,sha256=rxjQQrrIkpSLLDUOPf1OJI7MHxs36NZcVGBVIgVNh6w,8282
|
|
60
60
|
attune/cli/commands/sync.py,sha256=IE9kdpUl3G-Ep3XlZcZc_5JeUmGGfPxBpC2g_cp89H4,5086
|
|
61
61
|
attune/cli/commands/tier.py,sha256=ztb7GisxmlQWuoVrc7QRblKp5pM9bsLpZUBQBfM3Iw4,3737
|
|
62
|
-
attune/cli/commands/utilities.py,sha256=
|
|
62
|
+
attune/cli/commands/utilities.py,sha256=WZQsQwEGRWxfqKPPVdTlVg9Eb49uhZmccfxz5Llrckc,3709
|
|
63
63
|
attune/cli/commands/workflow.py,sha256=W2Mz5oyWZChCpGBonfbSlmSN5VQcjnO9nj8B2c1aliY,23549
|
|
64
64
|
attune/cli/parsers/__init__.py,sha256=Oihx1jb5wN_4GS3RxZiEYhQhglI44idOOlFJs9a6e5g,1677
|
|
65
65
|
attune/cli/parsers/batch.py,sha256=wSutRqerJZxUNVNIotU9qtI8EGP6IzVihEZUViCItCQ,3236
|
|
@@ -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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
272
|
-
attune/workflows/base.py,sha256=
|
|
273
|
-
attune/workflows/batch_processing.py,sha256=
|
|
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
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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.
|
|
351
|
-
attune_ai-2.1.
|
|
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.
|
|
454
|
-
attune_ai-2.1.
|
|
455
|
-
attune_ai-2.1.
|
|
456
|
-
attune_ai-2.1.
|
|
457
|
-
attune_ai-2.1.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{attune_ai-2.1.3.dist-info → attune_ai-2.1.5.dist-info}/licenses/LICENSE_CHANGE_ANNOUNCEMENT.md
RENAMED
|
File without changes
|
|
File without changes
|