attune-ai 2.1.1__py3-none-any.whl → 2.1.2__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.
@@ -0,0 +1,761 @@
1
+ """Socratic Router - Intent-based workflow discovery.
2
+
3
+ Routes user's natural language goals to AskUserQuestion options.
4
+ Used by the /attune command for Socratic discovery flow.
5
+
6
+ Two modes:
7
+ 1. Quick routing: Simple intent classification → AskUserQuestion options → skill invocation
8
+ 2. Deep discovery: Full SocraticWorkflowBuilder session for complex agent generation
9
+
10
+ Flow (Quick):
11
+ 1. User runs /attune
12
+ 2. Claude asks "What are you trying to accomplish?"
13
+ 3. User responds naturally
14
+ 4. classify_intent() detects category
15
+ 5. AskUserQuestion presents 2-4 relevant options
16
+ 6. User selects → routes to skill
17
+
18
+ Flow (Deep):
19
+ 1. User needs complex workflow generation
20
+ 2. SocraticWorkflowBuilder creates multi-round Q&A session
21
+ 3. form_to_ask_user_question() converts Forms to AskUserQuestion
22
+ 4. Generates custom agent workflow
23
+
24
+ Copyright 2025 Smart-AI-Memory
25
+ Licensed under Fair Source License 0.9
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ from dataclasses import dataclass
31
+ from enum import Enum
32
+ from typing import TYPE_CHECKING, Any
33
+
34
+ if TYPE_CHECKING:
35
+ from attune.socratic import Form, SocraticSession
36
+
37
+
38
+ class IntentCategory(Enum):
39
+ """High-level categories of user intent."""
40
+
41
+ FIX = "fix" # Debug, fix bugs, resolve errors
42
+ IMPROVE = "improve" # Refactor, optimize, clean up
43
+ VALIDATE = "validate" # Test, review, audit
44
+ SHIP = "ship" # Commit, PR, release
45
+ UNDERSTAND = "understand" # Explain, document, explore
46
+ UNKNOWN = "unknown" # Needs clarification
47
+
48
+
49
+ @dataclass
50
+ class WorkflowOption:
51
+ """A workflow option for AskUserQuestion.
52
+
53
+ Attributes:
54
+ label: Short label for the option (1-5 words)
55
+ description: What this option does
56
+ skill: The skill to invoke
57
+ args: Arguments for the skill
58
+ """
59
+
60
+ label: str
61
+ description: str
62
+ skill: str
63
+ args: str = ""
64
+
65
+ def to_ask_user_option(self) -> dict[str, str]:
66
+ """Convert to AskUserQuestion option format."""
67
+ return {"label": self.label, "description": self.description}
68
+
69
+
70
+ @dataclass
71
+ class IntentClassification:
72
+ """Result of classifying user intent.
73
+
74
+ Attributes:
75
+ category: Primary intent category
76
+ confidence: Confidence score (0-1)
77
+ keywords_matched: Keywords that triggered this classification
78
+ suggested_question: Question to ask via AskUserQuestion
79
+ options: Workflow options to present
80
+ """
81
+
82
+ category: IntentCategory
83
+ confidence: float
84
+ keywords_matched: list[str]
85
+ suggested_question: str
86
+ options: list[WorkflowOption]
87
+
88
+
89
+ # Intent detection patterns
90
+ INTENT_PATTERNS: dict[IntentCategory, dict[str, Any]] = {
91
+ IntentCategory.FIX: {
92
+ "keywords": [
93
+ "fix",
94
+ "bug",
95
+ "error",
96
+ "broken",
97
+ "crash",
98
+ "fail",
99
+ "issue",
100
+ "problem",
101
+ "debug",
102
+ "wrong",
103
+ "doesn't work",
104
+ "not working",
105
+ "exception",
106
+ "traceback",
107
+ ],
108
+ "question": "What kind of issue are you dealing with?",
109
+ "options": [
110
+ WorkflowOption(
111
+ label="Debug an error",
112
+ description="Investigate exceptions, trace execution, find root cause",
113
+ skill="dev",
114
+ args="debug",
115
+ ),
116
+ WorkflowOption(
117
+ label="Fix failing tests",
118
+ description="Analyze test failures and fix the underlying code",
119
+ skill="testing",
120
+ args="run",
121
+ ),
122
+ WorkflowOption(
123
+ label="Review for bugs",
124
+ description="Code review focused on finding potential bugs",
125
+ skill="dev",
126
+ args="review",
127
+ ),
128
+ WorkflowOption(
129
+ label="Something else",
130
+ description="Describe your specific issue",
131
+ skill="attune",
132
+ args="",
133
+ ),
134
+ ],
135
+ },
136
+ IntentCategory.IMPROVE: {
137
+ "keywords": [
138
+ "refactor",
139
+ "improve",
140
+ "clean",
141
+ "optimize",
142
+ "simplify",
143
+ "better",
144
+ "performance",
145
+ "speed",
146
+ "faster",
147
+ "memory",
148
+ "too long",
149
+ "complex",
150
+ "messy",
151
+ "ugly",
152
+ ],
153
+ "question": "What would you like to improve?",
154
+ "options": [
155
+ WorkflowOption(
156
+ label="Refactor code",
157
+ description="Improve structure, extract functions, simplify logic",
158
+ skill="dev",
159
+ args="refactor",
160
+ ),
161
+ WorkflowOption(
162
+ label="Optimize performance",
163
+ description="Find bottlenecks, improve speed and memory usage",
164
+ skill="workflows",
165
+ args="run perf-audit",
166
+ ),
167
+ WorkflowOption(
168
+ label="Code review",
169
+ description="Get feedback on code quality and patterns",
170
+ skill="dev",
171
+ args="review",
172
+ ),
173
+ WorkflowOption(
174
+ label="Something else",
175
+ description="Describe what you want to improve",
176
+ skill="attune",
177
+ args="",
178
+ ),
179
+ ],
180
+ },
181
+ IntentCategory.VALIDATE: {
182
+ "keywords": [
183
+ "test",
184
+ "coverage",
185
+ "security",
186
+ "audit",
187
+ "check",
188
+ "verify",
189
+ "validate",
190
+ "review",
191
+ "safe",
192
+ "secure",
193
+ "vulnerability",
194
+ ],
195
+ "question": "What would you like to validate?",
196
+ "options": [
197
+ WorkflowOption(
198
+ label="Run tests",
199
+ description="Execute test suite and see results",
200
+ skill="testing",
201
+ args="run",
202
+ ),
203
+ WorkflowOption(
204
+ label="Check coverage",
205
+ description="Analyze test coverage and identify gaps",
206
+ skill="testing",
207
+ args="coverage",
208
+ ),
209
+ WorkflowOption(
210
+ label="Security audit",
211
+ description="Scan for vulnerabilities and security issues",
212
+ skill="workflows",
213
+ args="run security-audit",
214
+ ),
215
+ WorkflowOption(
216
+ label="Code review",
217
+ description="Quality and pattern analysis",
218
+ skill="dev",
219
+ args="review",
220
+ ),
221
+ ],
222
+ },
223
+ IntentCategory.SHIP: {
224
+ "keywords": [
225
+ "commit",
226
+ "push",
227
+ "pr",
228
+ "pull request",
229
+ "merge",
230
+ "release",
231
+ "deploy",
232
+ "ship",
233
+ "publish",
234
+ "done",
235
+ "ready",
236
+ "finished",
237
+ ],
238
+ "question": "What stage are you at?",
239
+ "options": [
240
+ WorkflowOption(
241
+ label="Create commit",
242
+ description="Stage changes and create a commit with message",
243
+ skill="dev",
244
+ args="commit",
245
+ ),
246
+ WorkflowOption(
247
+ label="Create PR",
248
+ description="Push branch and create pull request",
249
+ skill="dev",
250
+ args="pr",
251
+ ),
252
+ WorkflowOption(
253
+ label="Prepare release",
254
+ description="Version bump, changelog, security checks",
255
+ skill="release",
256
+ args="prep",
257
+ ),
258
+ WorkflowOption(
259
+ label="Just push",
260
+ description="Push current commits to remote",
261
+ skill="dev",
262
+ args="push",
263
+ ),
264
+ ],
265
+ },
266
+ IntentCategory.UNDERSTAND: {
267
+ "keywords": [
268
+ "explain",
269
+ "understand",
270
+ "how",
271
+ "what",
272
+ "why",
273
+ "document",
274
+ "docs",
275
+ "readme",
276
+ "learn",
277
+ "show",
278
+ "describe",
279
+ "overview",
280
+ ],
281
+ "question": "What would you like to understand?",
282
+ "options": [
283
+ WorkflowOption(
284
+ label="Explain code",
285
+ description="Understand how specific code works",
286
+ skill="docs",
287
+ args="explain",
288
+ ),
289
+ WorkflowOption(
290
+ label="Project overview",
291
+ description="High-level architecture and structure",
292
+ skill="docs",
293
+ args="overview",
294
+ ),
295
+ WorkflowOption(
296
+ label="Generate docs",
297
+ description="Create or update documentation",
298
+ skill="docs",
299
+ args="generate",
300
+ ),
301
+ WorkflowOption(
302
+ label="Something specific",
303
+ description="Ask about a specific part of the codebase",
304
+ skill="attune",
305
+ args="",
306
+ ),
307
+ ],
308
+ },
309
+ }
310
+
311
+
312
+ def classify_intent(user_response: str) -> IntentClassification:
313
+ """Classify user's natural language response into intent category.
314
+
315
+ Args:
316
+ user_response: User's answer to "What are you trying to accomplish?"
317
+
318
+ Returns:
319
+ IntentClassification with category, options, and metadata
320
+ """
321
+ response_lower = user_response.lower()
322
+
323
+ best_category = IntentCategory.UNKNOWN
324
+ best_score = 0
325
+ matched_keywords: list[str] = []
326
+
327
+ # Score each category based on keyword matches
328
+ for category, pattern in INTENT_PATTERNS.items():
329
+ keywords = pattern["keywords"]
330
+ score = 0
331
+ matches = []
332
+
333
+ for keyword in keywords:
334
+ if keyword in response_lower:
335
+ score += 1
336
+ matches.append(keyword)
337
+
338
+ if score > best_score:
339
+ best_score = score
340
+ best_category = category
341
+ matched_keywords = matches
342
+
343
+ # Calculate confidence
344
+ if best_score == 0:
345
+ confidence = 0.0
346
+ elif best_score >= 3:
347
+ confidence = 0.95
348
+ elif best_score >= 2:
349
+ confidence = 0.8
350
+ else:
351
+ confidence = 0.6
352
+
353
+ # Get options for the category
354
+ if best_category in INTENT_PATTERNS:
355
+ pattern = INTENT_PATTERNS[best_category]
356
+ return IntentClassification(
357
+ category=best_category,
358
+ confidence=confidence,
359
+ keywords_matched=matched_keywords,
360
+ suggested_question=pattern["question"],
361
+ options=pattern["options"],
362
+ )
363
+
364
+ # Unknown intent - ask for clarification
365
+ return IntentClassification(
366
+ category=IntentCategory.UNKNOWN,
367
+ confidence=0.0,
368
+ keywords_matched=[],
369
+ suggested_question="Could you tell me more about what you're trying to do?",
370
+ options=[
371
+ WorkflowOption(
372
+ label="Fix something",
373
+ description="Debug errors, fix bugs, resolve issues",
374
+ skill="dev",
375
+ args="debug",
376
+ ),
377
+ WorkflowOption(
378
+ label="Improve code",
379
+ description="Refactor, optimize, clean up",
380
+ skill="dev",
381
+ args="refactor",
382
+ ),
383
+ WorkflowOption(
384
+ label="Validate work",
385
+ description="Test, review, audit for security",
386
+ skill="testing",
387
+ args="run",
388
+ ),
389
+ WorkflowOption(
390
+ label="Ship changes",
391
+ description="Commit, create PR, release",
392
+ skill="dev",
393
+ args="commit",
394
+ ),
395
+ ],
396
+ )
397
+
398
+
399
+ def get_ask_user_question_format(classification: IntentClassification) -> dict[str, Any]:
400
+ """Convert classification to AskUserQuestion tool format.
401
+
402
+ Args:
403
+ classification: Result from classify_intent()
404
+
405
+ Returns:
406
+ Dict ready to pass to AskUserQuestion tool
407
+ """
408
+ return {
409
+ "questions": [
410
+ {
411
+ "question": classification.suggested_question,
412
+ "header": classification.category.value.title(),
413
+ "options": [opt.to_ask_user_option() for opt in classification.options],
414
+ "multiSelect": False,
415
+ }
416
+ ]
417
+ }
418
+
419
+
420
+ def get_skill_for_selection(
421
+ classification: IntentClassification, selected_label: str
422
+ ) -> tuple[str, str]:
423
+ """Get skill and args for user's selection.
424
+
425
+ Args:
426
+ classification: The classification that was shown to user
427
+ selected_label: The label the user selected
428
+
429
+ Returns:
430
+ Tuple of (skill, args) to invoke
431
+ """
432
+ for option in classification.options:
433
+ if option.label == selected_label:
434
+ return option.skill, option.args
435
+
436
+ # Fallback to first option if not found
437
+ if classification.options:
438
+ return classification.options[0].skill, classification.options[0].args
439
+
440
+ return "attune", ""
441
+
442
+
443
+ # Convenience function for the /attune command
444
+ def process_socratic_response(user_response: str) -> dict[str, Any]:
445
+ """Process user's response to Socratic question.
446
+
447
+ This is the main entry point for the /attune command after
448
+ asking "What are you trying to accomplish?"
449
+
450
+ Args:
451
+ user_response: User's natural language response
452
+
453
+ Returns:
454
+ Dict with:
455
+ - classification: IntentClassification object
456
+ - ask_user_format: Ready-to-use AskUserQuestion format
457
+ - confidence: How confident we are in the classification
458
+ """
459
+ classification = classify_intent(user_response)
460
+
461
+ return {
462
+ "classification": classification,
463
+ "ask_user_format": get_ask_user_question_format(classification),
464
+ "confidence": classification.confidence,
465
+ "category": classification.category.value,
466
+ }
467
+
468
+
469
+ # =============================================================================
470
+ # DEEP DISCOVERY - SocraticWorkflowBuilder Integration
471
+ # =============================================================================
472
+
473
+
474
+ def form_to_ask_user_question(form: Form) -> dict[str, Any]:
475
+ """Convert a SocraticWorkflowBuilder Form to AskUserQuestion format.
476
+
477
+ This bridges the Socratic system's Form objects with Claude Code's
478
+ AskUserQuestion tool.
479
+
480
+ Args:
481
+ form: Form from SocraticWorkflowBuilder.get_next_questions()
482
+
483
+ Returns:
484
+ Dict ready to pass to AskUserQuestion tool
485
+
486
+ Example:
487
+ >>> from attune.socratic import SocraticWorkflowBuilder
488
+ >>> builder = SocraticWorkflowBuilder()
489
+ >>> session = builder.start_session("automate code reviews")
490
+ >>> form = builder.get_next_questions(session)
491
+ >>> ask_user_format = form_to_ask_user_question(form)
492
+ """
493
+ from attune.socratic.forms import FieldType
494
+
495
+ questions = []
496
+
497
+ for field in form.fields:
498
+ # Convert field to question format
499
+ question_data = {
500
+ "question": field.label,
501
+ "header": field.category.title() if field.category else "Question",
502
+ "multiSelect": field.field_type == FieldType.MULTI_SELECT,
503
+ "options": [],
504
+ }
505
+
506
+ # Convert options
507
+ if field.options:
508
+ for opt in field.options[:4]: # AskUserQuestion max 4 options
509
+ option_data = {"label": opt.value, "description": opt.description or opt.label}
510
+ if opt.recommended:
511
+ option_data["label"] += " (Recommended)"
512
+ question_data["options"].append(option_data)
513
+ else:
514
+ # Text field - provide generic options
515
+ question_data["options"] = [
516
+ {"label": "Continue", "description": "Proceed with current settings"},
517
+ {"label": "Customize", "description": "I want to specify details"},
518
+ ]
519
+
520
+ questions.append(question_data)
521
+
522
+ # Limit to 4 questions per AskUserQuestion call
523
+ return {"questions": questions[:4]}
524
+
525
+
526
+ def should_use_deep_discovery(user_response: str, classification: IntentClassification) -> bool:
527
+ """Determine if we should use full SocraticWorkflowBuilder.
528
+
529
+ Use deep discovery when:
530
+ - Low confidence classification
531
+ - User wants to create custom agents/workflows
532
+ - Complex multi-step requirements
533
+
534
+ Args:
535
+ user_response: User's natural language response
536
+ classification: Result from classify_intent()
537
+
538
+ Returns:
539
+ True if should use SocraticWorkflowBuilder, False for quick routing
540
+ """
541
+ # Low confidence - need more clarification
542
+ if classification.confidence < 0.5:
543
+ return True
544
+
545
+ # Explicit agent/workflow creation keywords
546
+ deep_keywords = [
547
+ "create agent",
548
+ "custom workflow",
549
+ "build workflow",
550
+ "automate",
551
+ "automation",
552
+ "generate agents",
553
+ "multi-step",
554
+ "pipeline",
555
+ ]
556
+
557
+ response_lower = user_response.lower()
558
+ for keyword in deep_keywords:
559
+ if keyword in response_lower:
560
+ return True
561
+
562
+ return False
563
+
564
+
565
+ def start_deep_discovery(goal: str) -> tuple[SocraticSession, dict[str, Any]]:
566
+ """Start a full SocraticWorkflowBuilder session.
567
+
568
+ Args:
569
+ goal: User's goal statement
570
+
571
+ Returns:
572
+ Tuple of (session, ask_user_format)
573
+
574
+ Example:
575
+ >>> session, questions = start_deep_discovery("automate security reviews")
576
+ >>> # Use questions with AskUserQuestion tool
577
+ >>> # Then call continue_deep_discovery(session, answers)
578
+ """
579
+ from attune.socratic import SocraticWorkflowBuilder
580
+
581
+ builder = SocraticWorkflowBuilder()
582
+ session = builder.start_session(goal)
583
+ form = builder.get_next_questions(session)
584
+
585
+ if form:
586
+ ask_user_format = form_to_ask_user_question(form)
587
+ else:
588
+ # Session ready to generate
589
+ ask_user_format = {
590
+ "questions": [
591
+ {
592
+ "question": "Ready to generate your workflow. Proceed?",
593
+ "header": "Generate",
594
+ "options": [
595
+ {"label": "Generate", "description": "Create the workflow now"},
596
+ {"label": "Add details", "description": "I want to specify more"},
597
+ ],
598
+ "multiSelect": False,
599
+ }
600
+ ]
601
+ }
602
+
603
+ return session, ask_user_format
604
+
605
+
606
+ def continue_deep_discovery(
607
+ session: SocraticSession, answers: dict[str, Any]
608
+ ) -> tuple[SocraticSession, dict[str, Any] | None]:
609
+ """Continue a SocraticWorkflowBuilder session with answers.
610
+
611
+ Args:
612
+ session: Active session from start_deep_discovery
613
+ answers: User's answers to previous questions
614
+
615
+ Returns:
616
+ Tuple of (updated_session, next_questions_or_None)
617
+ """
618
+ from attune.socratic import SocraticWorkflowBuilder
619
+
620
+ builder = SocraticWorkflowBuilder()
621
+ builder._sessions[session.session_id] = session
622
+
623
+ session = builder.submit_answers(session, answers)
624
+
625
+ if builder.is_ready_to_generate(session):
626
+ return session, None
627
+
628
+ form = builder.get_next_questions(session)
629
+ if form:
630
+ return session, form_to_ask_user_question(form)
631
+
632
+ return session, None
633
+
634
+
635
+ # =============================================================================
636
+ # UNIFIED ENTRY POINT
637
+ # =============================================================================
638
+
639
+
640
+ class AttuneRouter:
641
+ """Unified router for /attune command.
642
+
643
+ Handles both quick routing and deep discovery modes.
644
+
645
+ Example (Claude Code /attune command):
646
+ >>> router = AttuneRouter()
647
+ >>>
648
+ >>> # User says: "I need to fix a bug"
649
+ >>> result = router.process("I need to fix a bug")
650
+ >>>
651
+ >>> if result["mode"] == "quick":
652
+ >>> # Use AskUserQuestion with result["ask_user_format"]
653
+ >>> # Then call router.route_selection(result, user_selection)
654
+ >>>
655
+ >>> elif result["mode"] == "deep":
656
+ >>> # Multi-round discovery session
657
+ >>> # Use AskUserQuestion, then router.continue_session(...)
658
+ """
659
+
660
+ def __init__(self):
661
+ """Initialize the router."""
662
+ self._sessions: dict[str, SocraticSession] = {}
663
+
664
+ def process(self, user_response: str) -> dict[str, Any]:
665
+ """Process user's response and determine routing mode.
666
+
667
+ Args:
668
+ user_response: User's answer to "What are you trying to accomplish?"
669
+
670
+ Returns:
671
+ Dict with:
672
+ - mode: "quick" or "deep"
673
+ - ask_user_format: Ready for AskUserQuestion tool
674
+ - classification: (quick mode) IntentClassification
675
+ - session: (deep mode) SocraticSession
676
+ """
677
+ classification = classify_intent(user_response)
678
+
679
+ if should_use_deep_discovery(user_response, classification):
680
+ session, ask_user_format = start_deep_discovery(user_response)
681
+ self._sessions[session.session_id] = session
682
+
683
+ return {
684
+ "mode": "deep",
685
+ "session_id": session.session_id,
686
+ "ask_user_format": ask_user_format,
687
+ "classification": classification,
688
+ }
689
+ else:
690
+ return {
691
+ "mode": "quick",
692
+ "ask_user_format": get_ask_user_question_format(classification),
693
+ "classification": classification,
694
+ "category": classification.category.value,
695
+ }
696
+
697
+ def route_selection(
698
+ self, process_result: dict[str, Any], selected_label: str
699
+ ) -> dict[str, Any]:
700
+ """Route user's selection to skill invocation.
701
+
702
+ Args:
703
+ process_result: Result from process()
704
+ selected_label: Label user selected in AskUserQuestion
705
+
706
+ Returns:
707
+ Dict with skill and args to invoke
708
+ """
709
+ classification = process_result.get("classification")
710
+
711
+ if classification:
712
+ skill, args = get_skill_for_selection(classification, selected_label)
713
+ else:
714
+ skill, args = "attune", ""
715
+
716
+ return {
717
+ "skill": skill,
718
+ "args": args,
719
+ "instruction": f"Use Skill tool with skill='{skill}'"
720
+ + (f", args='{args}'" if args else ""),
721
+ }
722
+
723
+ def continue_session(
724
+ self, session_id: str, answers: dict[str, Any]
725
+ ) -> dict[str, Any]:
726
+ """Continue a deep discovery session.
727
+
728
+ Args:
729
+ session_id: Session ID from process() result
730
+ answers: User's answers to questions
731
+
732
+ Returns:
733
+ Dict with next questions or generated workflow
734
+ """
735
+ session = self._sessions.get(session_id)
736
+ if not session:
737
+ return {"error": "Session not found"}
738
+
739
+ session, next_questions = continue_deep_discovery(session, answers)
740
+ self._sessions[session_id] = session
741
+
742
+ if next_questions:
743
+ return {
744
+ "mode": "deep",
745
+ "session_id": session_id,
746
+ "ask_user_format": next_questions,
747
+ }
748
+ else:
749
+ # Ready to generate
750
+ from attune.socratic import SocraticWorkflowBuilder
751
+
752
+ builder = SocraticWorkflowBuilder()
753
+ builder._sessions[session_id] = session
754
+ workflow = builder.generate_workflow(session)
755
+
756
+ return {
757
+ "mode": "complete",
758
+ "session_id": session_id,
759
+ "workflow": workflow,
760
+ "summary": builder.get_session_summary(session),
761
+ }
attune/vscode_bridge.py CHANGED
@@ -43,10 +43,13 @@ class CodeReviewResult:
43
43
 
44
44
 
45
45
  def get_empathy_dir() -> Path:
46
- """Get the .empathy directory, creating if needed."""
47
- empathy_dir = Path(".empathy")
48
- empathy_dir.mkdir(exist_ok=True)
49
- return empathy_dir
46
+ """Get the .attune directory, creating if needed.
47
+
48
+ Note: Function retains 'empathy' name for backward compatibility.
49
+ """
50
+ attune_dir = Path(".attune")
51
+ attune_dir.mkdir(exist_ok=True)
52
+ return attune_dir
50
53
 
51
54
 
52
55
  def write_code_review_results(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: attune-ai
3
- Version: 2.1.1
3
+ Version: 2.1.2
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>
@@ -421,16 +421,17 @@ Requires-Dist: aiohttp<4.0.0,>=3.10.0; extra == "all"
421
421
  Requires-Dist: filelock<4.0.0,>=3.16.0; extra == "all"
422
422
  Dynamic: license-file
423
423
 
424
- # attune-ai
424
+ # Empathy Framework
425
425
 
426
- **AI-powered developer workflows with Socratic discovery.**
426
+ **AI-powered developer workflows with cost optimization and pattern learning.**
427
427
 
428
- Run code review, debugging, testing, and release workflows from Claude Code. One command guides you to the right workflow.
428
+ Run code review, debugging, testing, and release workflows from your terminal or Claude Code. Smart tier routing saves 34-86% on LLM costs.
429
429
 
430
430
  [![PyPI](https://img.shields.io/pypi/v/attune-ai?color=blue)](https://pypi.org/project/attune-ai/)
431
431
  [![Tests](https://img.shields.io/badge/tests-7%2C168%20passing%20(99.9%25)-brightgreen)](https://github.com/Smart-AI-Memory/attune-ai/actions)
432
432
  [![Python](https://img.shields.io/badge/python-3.10+-blue)](https://www.python.org)
433
433
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
434
+ [![Performance](https://img.shields.io/badge/performance-18x%20faster-success)](https://github.com/Smart-AI-Memory/attune-ai/blob/main/CHANGELOG.md)
434
435
 
435
436
  ```bash
436
437
  pip install attune-ai[developer]
@@ -438,26 +439,188 @@ pip install attune-ai[developer]
438
439
 
439
440
  ---
440
441
 
441
- ## What's New in v2.1.0
442
+ ## 🎯 Transitioning to Claude-Native Architecture
442
443
 
443
- **🎯 Unified `/attune` Command** - One entry point for all workflows:
444
+ **Empathy Framework is evolving to focus exclusively on Anthropic/Claude** to unlock features impossible with multi-provider abstraction:
445
+
446
+ - **📦 Prompt Caching:** 90% cost reduction on repeated prompts
447
+ - **📖 Flexible Context:** 200K via subscription for most tasks, up to 1M via API for large codebases
448
+ - **🧠 Extended Thinking:** See Claude's internal reasoning process
449
+ - **🔧 Advanced Tool Use:** Optimized for agentic workflows
450
+
451
+ **Timeline:**
452
+
453
+ - ✅ **v4.8.0 (Jan 2026):** Deprecation warnings for OpenAI/Google/Ollama providers
454
+ - ✅ **v5.0.0 (Jan 26, 2026):** Non-Anthropic providers removed (BREAKING - COMPLETE)
455
+ - ✅ **v5.0.2 (Jan 28, 2026):** Cost optimization suite with batch processing and caching monitoring
456
+
457
+ **Migration Guide:** [docs/CLAUDE_NATIVE.md](docs/CLAUDE_NATIVE.md)
458
+
459
+ ---
460
+
461
+ ## What's New in v5.3.0
462
+
463
+ **🎨 Dashboard Enhancements** - Improved usability and clarity:
464
+
465
+ - **Agent Display Names** - Human-readable labels for agents in dashboard (e.g., "Code Analyzer" instead of UUID)
466
+ - **Comprehensive Help Panel** - 5-section accordion explaining dashboard features, use cases, and Redis setup
467
+ - **UX Improvements** - "Source Agent:" label clarity, "Redis Requires Enabling" status message
468
+ - **Browser Cache Busting** - Date-based versioning ensures updates appear immediately
469
+
470
+ **📚 Documentation Improvements**:
471
+
472
+ - Clarified flexible context strategy (200K subscription + 1M API routing)
473
+ - Added Redis requirement documentation for dashboard
474
+ - Root directory cleanup (8 archived files)
475
+
476
+ **🧪 Test Infrastructure**:
477
+
478
+ - Sequential test execution to fix import timing issues
479
+ - All agent tracking tests passing (19/19)
480
+
481
+ [See Full Changelog](CHANGELOG.md#530---2026-01-31)
482
+
483
+ ---
484
+
485
+ ## What's New in v5.1.0
486
+
487
+ **🤖 Multi-Agent Orchestration** - Full support for custom agents and Anthropic LLM agents:
488
+
489
+ - **Agent Coordination Dashboard** - Real-time monitoring with 6 coordination patterns:
490
+ - Agent heartbeats and status tracking
491
+ - Inter-agent coordination signals
492
+ - Event streaming across agent workflows
493
+ - Approval gates for human-in-the-loop
494
+ - Quality feedback and performance metrics
495
+ - Demo mode with test data generation
496
+
497
+ - **Custom Agents** - Build specialized agents for your workflow needs
498
+ - **LLM Agents from Anthropic** - Leverage Claude's advanced capabilities
499
+ - Dashboard accessible at `http://localhost:8000` with `python examples/dashboard_demo.py` **(Requires Redis)**
500
+
501
+ **🔐 Authentication Strategy System** - Intelligent routing between Claude subscriptions and Anthropic API:
444
502
 
445
503
  ```bash
446
- /attune # Start Socratic discovery
447
- /attune "fix a bug" # Natural language
448
- /attune debug # Direct shortcut
504
+ # Interactive setup
505
+ python -m attune.models.auth_cli setup
506
+
507
+ # View current configuration
508
+ python -m attune.models.auth_cli status
509
+
510
+ # Get recommendation for a file
511
+ python -m attune.models.auth_cli recommend src/module.py
449
512
  ```
450
513
 
451
- **Socratic Discovery** - Ask what you're trying to accomplish, not which tool to use:
514
+ **💰 Automatic Cost Optimization** - Workflows choose the best auth method:
515
+
516
+ - Small/medium modules (<2000 LOC) → Claude subscription (free)
517
+ - Large modules (>2000 LOC) → Anthropic API (pay for what you need)
518
+ - 7 workflows integrated: document-gen, test-gen, code-review, bug-predict, security-audit, perf-audit, release-prep
519
+ - Auth mode tracking in all workflow outputs for telemetry
520
+
521
+ **🧪 Comprehensive Testing** - 7 new integration tests for auth strategy:
522
+
523
+ - All workflows tested with auth enabled/disabled
524
+ - API and subscription mode verification
525
+ - Cost tracking validation
526
+
527
+ **📖 Documentation** - 950+ lines across 3 guides:
528
+
529
+ - [AUTH_STRATEGY_GUIDE.md](docs/AUTH_STRATEGY_GUIDE.md) - User guide for configuration
530
+ - [AUTH_CLI_IMPLEMENTATION.md](docs/AUTH_CLI_IMPLEMENTATION.md) - CLI command reference
531
+ - [AUTH_WORKFLOW_INTEGRATIONS.md](docs/AUTH_WORKFLOW_INTEGRATIONS.md) - Integration patterns
532
+
533
+ [See Full Changelog](CHANGELOG.md#510---2026-01-29)
534
+
535
+ ---
536
+
537
+ ## What's New in v5.0.2
538
+
539
+ **💰 50% Cost Savings with Batch API** - Process non-urgent tasks asynchronously:
540
+
541
+ ```bash
542
+ empathy batch submit batch_requests.json # Submit batch job
543
+ empathy batch status msgbatch_abc123 # Check progress
544
+ empathy batch results msgbatch_abc123 output.json # Download results
545
+ ```
546
+
547
+ Perfect for: log analysis, report generation, bulk classification, test generation
548
+
549
+ **📊 Precise Token Counting** - >98% accurate cost tracking:
550
+
551
+ - Integrated Anthropic's `count_tokens()` API for billing-accurate measurements
552
+ - 3-tier fallback: API → tiktoken (local) → heuristic
553
+ - Cache-aware cost calculation (25% write markup, 90% read discount)
554
+
555
+ **📈 Cache Performance Monitoring** - Track your 20-30% caching savings:
556
+
557
+ ```bash
558
+ empathy cache stats # Show hit rates and cost savings
559
+ empathy cache stats --verbose # Detailed token metrics
560
+ empathy cache stats --format json # Machine-readable output
561
+ ```
562
+
563
+ **🧭 Adaptive Routing Analytics** - Intelligent tier recommendations:
564
+
565
+ ```bash
566
+ empathy routing stats <workflow> # Performance metrics
567
+ empathy routing check --all # Tier upgrade recommendations
568
+ empathy routing models --provider anthropic # Compare models
569
+ ```
570
+
571
+ **🔧 Dashboard Fixes** - All 6 agent coordination patterns now operational:
572
+ - Agent heartbeats displaying correctly
573
+ - Event streaming functional
574
+ - Coordination signals working
575
+ - Approval gates operational
576
+
577
+ [See Full Changelog](CHANGELOG.md#502---2026-01-28) | [Batch API Guide](docs/BATCH_API_GUIDE.md) | [User API Docs](docs/USER_API_DOCUMENTATION.md)
578
+
579
+ ---
580
+
581
+ ## What's New in v4.9.0
582
+
583
+ **⚡ 18x Faster Performance** - Massive performance gains through Phase 2 optimizations:
584
+
585
+ - **Redis Two-Tier Caching:** 2x faster memory operations (37,000x for cached keys)
586
+ - **Generator Expressions:** 99.9% memory reduction across 27 optimizations
587
+ - **Parallel Scanning:** Multi-core processing enabled by default (2-4x faster)
588
+ - **Incremental Scanning:** Git diff-based updates (10x faster)
589
+
590
+ **🧭 Natural Language Workflows** - Use plain English instead of workflow names:
591
+
592
+ ```bash
593
+ /workflows "find security vulnerabilities" # → security-audit
594
+ /workflows "check code performance" # → perf-audit
595
+ /workflows "predict bugs" # → bug-predict
596
+ /plan "review my code" # → code-review
597
+ ```
598
+
599
+ **📊 Real-World Performance:**
600
+
601
+ - Combined workflow: 3.59s → 0.2s (**18x faster**)
602
+ - Full scan: 3,472 files in 0.98s (was 3.59s)
603
+ - Redis cached operations: 37ms → 0.001ms
604
+
605
+ **🎯 Improved Navigation:**
606
+
607
+ - Split `/workflow` into `/workflows` (automated analysis) and `/plan` (planning/review)
608
+ - Clearer hub organization with better categorization
609
+ - Natural language routing matches intent to workflow
610
+
611
+ [See CHANGELOG.md](CHANGELOG.md) | [Performance Docs](docs/REDIS_OPTIMIZATION_SUMMARY.md)
612
+
613
+ ---
614
+
615
+ ## What's New in v4.7.0
616
+
617
+ **$0 Workflows via Skills** - Multi-agent workflows run through Claude Code's Task tool instead of API calls. No additional cost with your Claude subscription.
452
618
 
453
- - 🔧 **Fix or improve** Debug, review, refactor
454
- - ✅ **Validate work** → Tests, coverage, security audit
455
- - 🚀 **Ship changes** → Commit, PR, release
456
- - 📚 **Understand** → Explain code, generate docs
619
+ **Socratic Workflows** - Interactive discovery through guided questions. Workflows ask what you need rather than requiring upfront configuration.
457
620
 
458
- **Performance Audit Improvements** - Removed false positive detection for intentional patterns like `dirs[:]` and defensive list copies.
621
+ **Security Hardened** - Fixed critical vulnerabilities (path traversal, JWT, SSRF).
459
622
 
460
- [See Full Changelog](CHANGELOG.md)
623
+ **Hub-Based Commands** - Organized workflows into intuitive command hubs.
461
624
 
462
625
  ---
463
626
 
@@ -23,11 +23,12 @@ attune/persistence.py,sha256=wsEJtHdjpEfIQ3-O5PaxAGiZXacON0Pft4gqt7Ui3z8,17714
23
23
  attune/platform_utils.py,sha256=NsvAOOA2QgdWLd_44AY1UdQLYuclaOC7SPK-koFyi1A,7384
24
24
  attune/redis_config.py,sha256=jDpnKXxBoAo6Cy2oBX9imbRtsUAyPKOIH6jvSlWdcbU,9742
25
25
  attune/redis_memory.py,sha256=MYhW_M41AoWhxxh8YggWUHxZaUoQZ7XxqeBB2qDqyww,23347
26
+ attune/socratic_router.py,sha256=sHEPYDC88n6OaGBtnC7JquyctldBp3tSCQdrphV0BHo,23601
26
27
  attune/templates.py,sha256=EbZmiHqS_jFZg_-lScK0fUUnw7_KpE5J3ZFTWXEKx-Q,17187
27
28
  attune/tier_recommender.py,sha256=rBuAgGkNlX9wWcJ1QFi0ASGuZSR9RGl6PEBElxcAzMk,14297
28
29
  attune/tools.py,sha256=YCfHTm9Es6wwh7oESt4q0mDz7AV8ecvMAB_1_0516r4,6225
29
30
  attune/trust_building.py,sha256=z2ZsQWK5QjX6d7pxFWrFD54J1keUguTog6YztZJVPKI,19180
30
- attune/vscode_bridge.py,sha256=ToUx4QvfRXQeSmh10sz7gzzEYMBymOTqJ6Zt4RE9YK4,4963
31
+ attune/vscode_bridge.py,sha256=XBKF6-YiQIRvyOtkp-4kmBrWhs5Uflo7TLUBj4ejPLU,5034
31
32
  attune/workflow_commands.py,sha256=9Gdy3iI6LA9y7NtYBieNS3-rbOrrLRavhlbl_2yWVgU,25465
32
33
  attune/adaptive/__init__.py,sha256=9LRWvrkitzasuGAqANEpKQMvrj5pPNtulSxz49E-Ke4,338
33
34
  attune/adaptive/task_complexity.py,sha256=XhQgubrTxqV2V6CBD4kKZ_0kPCjchzg94HaUFIY6Q3c,3783
@@ -346,8 +347,8 @@ attune/workflows/test_gen/data_models.py,sha256=wXfef60ptiG6AvygayTxWqlL5FVOss19
346
347
  attune/workflows/test_gen/report_formatter.py,sha256=RaxbDp6-9iQRfJmVwrrIReVkOkrnb668NgHrNaS-SPY,10705
347
348
  attune/workflows/test_gen/test_templates.py,sha256=4ywqGYYaSoZxOU6Y1_E-27KEgMI5-v2a1ndia406E9c,13180
348
349
  attune/workflows/test_gen/workflow.py,sha256=U0dhAcCKmlltPIvCSXUeFzt_Q4TodQI4tXtR6cz19MQ,25729
349
- attune_ai-2.1.1.dist-info/licenses/LICENSE,sha256=kqe3EeGatNB79lUTHxjLnxDe7VJr0iYetThOr4_Fx7A,11348
350
- attune_ai-2.1.1.dist-info/licenses/LICENSE_CHANGE_ANNOUNCEMENT.md,sha256=JH9yAQGv_lQej5YlztI_kawbVQ2H8uVLhPGlrWnR_34,3844
350
+ attune_ai-2.1.2.dist-info/licenses/LICENSE,sha256=kqe3EeGatNB79lUTHxjLnxDe7VJr0iYetThOr4_Fx7A,11348
351
+ attune_ai-2.1.2.dist-info/licenses/LICENSE_CHANGE_ANNOUNCEMENT.md,sha256=JH9yAQGv_lQej5YlztI_kawbVQ2H8uVLhPGlrWnR_34,3844
351
352
  attune_healthcare/__init__.py,sha256=4NioL1_86UXzkd-QNkQZUSZ8rKTQGSP0TC9VXP32kQs,295
352
353
  attune_healthcare/monitors/__init__.py,sha256=Udp8qfZR504QAq5_eQjvtIaE7v06Yguc7nuF40KllQc,196
353
354
  attune_healthcare/monitors/clinical_protocol_monitor.py,sha256=MWE5t8tW9HWZn_SNo-inx8-0nhdTNGhbcB8ZeDWyXa0,11648
@@ -449,8 +450,8 @@ workflow_scaffolding/__init__.py,sha256=UpX5vjjjPjIaAKyIV1D4GxJzLUZy5DzdzgSkePYM
449
450
  workflow_scaffolding/__main__.py,sha256=0qspuNoadTDqyskXTlT8Sahqau-XIxN35NHTSGVW6z4,236
450
451
  workflow_scaffolding/cli.py,sha256=RUVqU9SeAgm7YkM0YNd-quh8u6BNzmX8xM2y9K_p68Y,6759
451
452
  workflow_scaffolding/generator.py,sha256=2WC02A10lzF2NQgOn66ksV17Oe72kKlU2qCQs39LIlw,8861
452
- attune_ai-2.1.1.dist-info/METADATA,sha256=EI1tND_AQuj_XW98SejMJ2p0UFRnfrjDQu1KL26jK3k,38450
453
- attune_ai-2.1.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
454
- attune_ai-2.1.1.dist-info/entry_points.txt,sha256=GVlb04zFlpkaPtaL7X3JCZI8R0AEOZRsZjJ-wIDQvdo,1458
455
- attune_ai-2.1.1.dist-info/top_level.txt,sha256=iLyjKpuOzWtwmIOZqzeBh8_SVztY2vFvhHcyo1WPtTY,73
456
- attune_ai-2.1.1.dist-info/RECORD,,
453
+ attune_ai-2.1.2.dist-info/METADATA,sha256=4aE_g9pNuVToXXW4Zwf9ck-CJUcMG_e8MZ7jMukCkFE,45033
454
+ attune_ai-2.1.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
455
+ attune_ai-2.1.2.dist-info/entry_points.txt,sha256=GVlb04zFlpkaPtaL7X3JCZI8R0AEOZRsZjJ-wIDQvdo,1458
456
+ attune_ai-2.1.2.dist-info/top_level.txt,sha256=iLyjKpuOzWtwmIOZqzeBh8_SVztY2vFvhHcyo1WPtTY,73
457
+ attune_ai-2.1.2.dist-info/RECORD,,