empathy-framework 4.1.1__py3-none-any.whl → 4.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. {empathy_framework-4.1.1.dist-info → empathy_framework-4.4.0.dist-info}/METADATA +77 -12
  2. {empathy_framework-4.1.1.dist-info → empathy_framework-4.4.0.dist-info}/RECORD +45 -14
  3. empathy_os/cli_unified.py +13 -0
  4. empathy_os/memory/long_term.py +5 -0
  5. empathy_os/memory/unified.py +149 -9
  6. empathy_os/meta_workflows/__init__.py +74 -0
  7. empathy_os/meta_workflows/agent_creator.py +254 -0
  8. empathy_os/meta_workflows/builtin_templates.py +567 -0
  9. empathy_os/meta_workflows/cli_meta_workflows.py +1551 -0
  10. empathy_os/meta_workflows/form_engine.py +304 -0
  11. empathy_os/meta_workflows/intent_detector.py +298 -0
  12. empathy_os/meta_workflows/models.py +567 -0
  13. empathy_os/meta_workflows/pattern_learner.py +754 -0
  14. empathy_os/meta_workflows/session_context.py +398 -0
  15. empathy_os/meta_workflows/template_registry.py +229 -0
  16. empathy_os/meta_workflows/workflow.py +980 -0
  17. empathy_os/orchestration/execution_strategies.py +888 -1
  18. empathy_os/orchestration/pattern_learner.py +699 -0
  19. empathy_os/socratic/__init__.py +273 -0
  20. empathy_os/socratic/ab_testing.py +969 -0
  21. empathy_os/socratic/blueprint.py +532 -0
  22. empathy_os/socratic/cli.py +689 -0
  23. empathy_os/socratic/collaboration.py +1112 -0
  24. empathy_os/socratic/domain_templates.py +916 -0
  25. empathy_os/socratic/embeddings.py +734 -0
  26. empathy_os/socratic/engine.py +729 -0
  27. empathy_os/socratic/explainer.py +663 -0
  28. empathy_os/socratic/feedback.py +767 -0
  29. empathy_os/socratic/forms.py +624 -0
  30. empathy_os/socratic/generator.py +716 -0
  31. empathy_os/socratic/llm_analyzer.py +635 -0
  32. empathy_os/socratic/mcp_server.py +751 -0
  33. empathy_os/socratic/session.py +306 -0
  34. empathy_os/socratic/storage.py +635 -0
  35. empathy_os/socratic/success.py +719 -0
  36. empathy_os/socratic/visual_editor.py +812 -0
  37. empathy_os/socratic/web_ui.py +925 -0
  38. empathy_os/workflows/manage_documentation.py +18 -2
  39. empathy_os/workflows/release_prep_crew.py +16 -1
  40. empathy_os/workflows/test_coverage_boost_crew.py +16 -1
  41. empathy_os/workflows/test_maintenance_crew.py +18 -1
  42. {empathy_framework-4.1.1.dist-info → empathy_framework-4.4.0.dist-info}/WHEEL +0 -0
  43. {empathy_framework-4.1.1.dist-info → empathy_framework-4.4.0.dist-info}/entry_points.txt +0 -0
  44. {empathy_framework-4.1.1.dist-info → empathy_framework-4.4.0.dist-info}/licenses/LICENSE +0 -0
  45. {empathy_framework-4.1.1.dist-info → empathy_framework-4.4.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,254 @@
1
+ """Dynamic agent creator from templates and form responses.
2
+
3
+ Generates agent specifications based on template rules and user's
4
+ form responses. Core of the meta-workflow system's agent composition.
5
+
6
+ Created: 2026-01-17
7
+ Purpose: Dynamic agent team generation
8
+ """
9
+
10
+ import logging
11
+ from typing import Any
12
+
13
+ from empathy_os.meta_workflows.models import (
14
+ AgentCompositionRule,
15
+ AgentSpec,
16
+ FormResponse,
17
+ MetaWorkflowTemplate,
18
+ TierStrategy,
19
+ )
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+
24
+ class DynamicAgentCreator:
25
+ """Creates agent teams dynamically from templates and form responses.
26
+
27
+ Takes a meta-workflow template and user's form responses, then generates
28
+ a list of agent specifications based on the template's composition rules.
29
+ """
30
+
31
+ def __init__(self):
32
+ """Initialize the dynamic agent creator."""
33
+ self.creation_stats: dict[str, int] = {
34
+ "total_rules_evaluated": 0,
35
+ "agents_created": 0,
36
+ "rules_skipped": 0,
37
+ }
38
+
39
+ def create_agents(
40
+ self, template: MetaWorkflowTemplate, form_response: FormResponse
41
+ ) -> list[AgentSpec]:
42
+ """Create agents from template rules and form responses.
43
+
44
+ Args:
45
+ template: Meta-workflow template with composition rules
46
+ form_response: User's responses to form questions
47
+
48
+ Returns:
49
+ List of AgentSpec instances to execute
50
+
51
+ Raises:
52
+ ValueError: If template or form_response is invalid
53
+ """
54
+ if not template.agent_composition_rules:
55
+ logger.warning(f"Template {template.template_id} has no composition rules")
56
+ return []
57
+
58
+ agents = []
59
+ self.creation_stats["total_rules_evaluated"] = len(
60
+ template.agent_composition_rules
61
+ )
62
+
63
+ logger.info(
64
+ f"Evaluating {len(template.agent_composition_rules)} composition rules"
65
+ )
66
+
67
+ for rule in template.agent_composition_rules:
68
+ # Check if agent should be created based on form responses
69
+ if rule.should_create(form_response):
70
+ agent = self._create_agent_from_rule(rule, form_response)
71
+ agents.append(agent)
72
+ self.creation_stats["agents_created"] += 1
73
+
74
+ logger.debug(
75
+ f"Created agent: {agent.role} "
76
+ f"(tier: {agent.tier_strategy.value}, id: {agent.agent_id})"
77
+ )
78
+ else:
79
+ self.creation_stats["rules_skipped"] += 1
80
+ logger.debug(
81
+ f"Skipped agent {rule.role} - conditions not met"
82
+ )
83
+
84
+ logger.info(
85
+ f"Created {len(agents)} agents from {len(template.agent_composition_rules)} rules"
86
+ )
87
+
88
+ return agents
89
+
90
+ def _create_agent_from_rule(
91
+ self, rule: AgentCompositionRule, form_response: FormResponse
92
+ ) -> AgentSpec:
93
+ """Create an AgentSpec from a composition rule and form responses.
94
+
95
+ Args:
96
+ rule: Agent composition rule
97
+ form_response: User's form responses
98
+
99
+ Returns:
100
+ AgentSpec instance configured for execution
101
+ """
102
+ # Map config from form responses
103
+ config = rule.create_agent_config(form_response)
104
+
105
+ # Create agent spec
106
+ agent = AgentSpec(
107
+ role=rule.role,
108
+ base_template=rule.base_template,
109
+ tier_strategy=rule.tier_strategy,
110
+ tools=rule.tools.copy(), # Copy to avoid mutation
111
+ config=config,
112
+ success_criteria=rule.success_criteria.copy(), # Copy to avoid mutation
113
+ )
114
+
115
+ return agent
116
+
117
+ def get_creation_stats(self) -> dict[str, int]:
118
+ """Get statistics about agent creation.
119
+
120
+ Returns:
121
+ Dictionary with creation statistics
122
+ """
123
+ return self.creation_stats.copy()
124
+
125
+ def reset_stats(self) -> None:
126
+ """Reset creation statistics."""
127
+ self.creation_stats = {
128
+ "total_rules_evaluated": 0,
129
+ "agents_created": 0,
130
+ "rules_skipped": 0,
131
+ }
132
+ logger.debug("Agent creation stats reset")
133
+
134
+
135
+ # =============================================================================
136
+ # Helper functions for agent composition
137
+ # =============================================================================
138
+
139
+
140
+ def group_agents_by_tier_strategy(
141
+ agents: list[AgentSpec],
142
+ ) -> dict[TierStrategy, list[AgentSpec]]:
143
+ """Group agents by their tier strategy.
144
+
145
+ Useful for execution planning (e.g., run all cheap_only agents first).
146
+
147
+ Args:
148
+ agents: List of agent specs
149
+
150
+ Returns:
151
+ Dictionary mapping TierStrategy → list of agents
152
+
153
+ Example:
154
+ >>> agents = [
155
+ ... AgentSpec(role="test", base_template="generic", tier_strategy=TierStrategy.CHEAP_ONLY),
156
+ ... AgentSpec(role="review", base_template="generic", tier_strategy=TierStrategy.PROGRESSIVE),
157
+ ... ]
158
+ >>> grouped = group_agents_by_tier_strategy(agents)
159
+ >>> len(grouped[TierStrategy.CHEAP_ONLY])
160
+ 1
161
+ """
162
+ grouped: dict[TierStrategy, list[AgentSpec]] = {}
163
+
164
+ for agent in agents:
165
+ if agent.tier_strategy not in grouped:
166
+ grouped[agent.tier_strategy] = []
167
+ grouped[agent.tier_strategy].append(agent)
168
+
169
+ return grouped
170
+
171
+
172
+ def estimate_agent_costs(
173
+ agents: list[AgentSpec], cost_per_tier: dict[str, float] | None = None
174
+ ) -> dict[str, Any]:
175
+ """Estimate total cost for executing agents.
176
+
177
+ Args:
178
+ agents: List of agent specs
179
+ cost_per_tier: Optional cost mapping (tier → estimated cost)
180
+ Defaults to reasonable estimates
181
+
182
+ Returns:
183
+ Dictionary with cost estimates
184
+
185
+ Example:
186
+ >>> agents = [AgentSpec(role="test", base_template="generic", tier_strategy=TierStrategy.CHEAP_ONLY)]
187
+ >>> estimate_agent_costs(agents)
188
+ {'total_estimated_cost': 0.05, 'by_tier': {'cheap_only': 0.05}, 'agent_count': 1}
189
+ """
190
+ if cost_per_tier is None:
191
+ # Default cost estimates per tier strategy
192
+ cost_per_tier = {
193
+ "cheap_only": 0.05,
194
+ "progressive": 0.15, # Average, might escalate
195
+ "capable_first": 0.25, # Starts higher
196
+ "premium_only": 0.40,
197
+ }
198
+
199
+ total_cost = 0.0
200
+ cost_by_tier: dict[str, float] = {}
201
+
202
+ for agent in agents:
203
+ tier_key = agent.tier_strategy.value
204
+ agent_cost = cost_per_tier.get(tier_key, 0.10) # Default fallback
205
+
206
+ total_cost += agent_cost
207
+
208
+ if tier_key not in cost_by_tier:
209
+ cost_by_tier[tier_key] = 0.0
210
+ cost_by_tier[tier_key] += agent_cost
211
+
212
+ return {
213
+ "total_estimated_cost": round(total_cost, 2),
214
+ "by_tier": {k: round(v, 2) for k, v in cost_by_tier.items()},
215
+ "agent_count": len(agents),
216
+ }
217
+
218
+
219
+ def validate_agent_dependencies(agents: list[AgentSpec]) -> list[str]:
220
+ """Validate that agent dependencies are satisfied.
221
+
222
+ Checks for common dependency issues (e.g., publisher needs package_builder).
223
+
224
+ Args:
225
+ agents: List of agent specs
226
+
227
+ Returns:
228
+ List of validation warnings (empty if all OK)
229
+
230
+ Example:
231
+ >>> agents = [AgentSpec(role="publisher", base_template="generic", tier_strategy=TierStrategy.CHEAP_ONLY)]
232
+ >>> warnings = validate_agent_dependencies(agents)
233
+ >>> len(warnings) > 0 # Should warn about missing package_builder
234
+ True
235
+ """
236
+ warnings = []
237
+ agent_roles = {agent.role for agent in agents}
238
+
239
+ # Common dependencies
240
+ dependencies = {
241
+ "publisher": ["package_builder"],
242
+ "changelog_updater": ["version_manager"],
243
+ }
244
+
245
+ for agent in agents:
246
+ if agent.role in dependencies:
247
+ for required_role in dependencies[agent.role]:
248
+ if required_role not in agent_roles:
249
+ warnings.append(
250
+ f"Agent '{agent.role}' typically requires '{required_role}' "
251
+ f"but it's not in the agent list"
252
+ )
253
+
254
+ return warnings