crca 1.4.0__py3-none-any.whl → 1.5.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 (306) hide show
  1. CRCA.py +172 -7
  2. MODEL_CARD.md +53 -0
  3. PKG-INFO +8 -2
  4. RELEASE_NOTES.md +17 -0
  5. STABILITY.md +19 -0
  6. architecture/hybrid/consistency_engine.py +362 -0
  7. architecture/hybrid/conversation_manager.py +421 -0
  8. architecture/hybrid/explanation_generator.py +452 -0
  9. architecture/hybrid/few_shot_learner.py +533 -0
  10. architecture/hybrid/graph_compressor.py +286 -0
  11. architecture/hybrid/hybrid_agent.py +4398 -0
  12. architecture/hybrid/language_compiler.py +623 -0
  13. architecture/hybrid/main,py +0 -0
  14. architecture/hybrid/reasoning_tracker.py +322 -0
  15. architecture/hybrid/self_verifier.py +524 -0
  16. architecture/hybrid/task_decomposer.py +567 -0
  17. architecture/hybrid/text_corrector.py +341 -0
  18. benchmark_results/crca_core_benchmarks.json +178 -0
  19. branches/crca_sd/crca_sd_realtime.py +6 -2
  20. branches/general_agent/__init__.py +102 -0
  21. branches/general_agent/general_agent.py +1400 -0
  22. branches/general_agent/personality.py +169 -0
  23. branches/general_agent/utils/__init__.py +19 -0
  24. branches/general_agent/utils/prompt_builder.py +170 -0
  25. {crca-1.4.0.dist-info → crca-1.5.0.dist-info}/METADATA +8 -2
  26. {crca-1.4.0.dist-info → crca-1.5.0.dist-info}/RECORD +303 -20
  27. crca_core/__init__.py +35 -0
  28. crca_core/benchmarks/__init__.py +14 -0
  29. crca_core/benchmarks/synthetic_scm.py +103 -0
  30. crca_core/core/__init__.py +23 -0
  31. crca_core/core/api.py +120 -0
  32. crca_core/core/estimate.py +208 -0
  33. crca_core/core/godclass.py +72 -0
  34. crca_core/core/intervention_design.py +174 -0
  35. crca_core/core/lifecycle.py +48 -0
  36. crca_core/discovery/__init__.py +9 -0
  37. crca_core/discovery/tabular.py +193 -0
  38. crca_core/identify/__init__.py +171 -0
  39. crca_core/identify/backdoor.py +39 -0
  40. crca_core/identify/frontdoor.py +48 -0
  41. crca_core/identify/graph.py +106 -0
  42. crca_core/identify/id_algorithm.py +43 -0
  43. crca_core/identify/iv.py +48 -0
  44. crca_core/models/__init__.py +67 -0
  45. crca_core/models/provenance.py +56 -0
  46. crca_core/models/refusal.py +39 -0
  47. crca_core/models/result.py +83 -0
  48. crca_core/models/spec.py +151 -0
  49. crca_core/models/validation.py +68 -0
  50. crca_core/scm/__init__.py +9 -0
  51. crca_core/scm/linear_gaussian.py +198 -0
  52. crca_core/timeseries/__init__.py +6 -0
  53. crca_core/timeseries/pcmci.py +181 -0
  54. crca_llm/__init__.py +12 -0
  55. crca_llm/client.py +85 -0
  56. crca_llm/coauthor.py +118 -0
  57. crca_llm/orchestrator.py +289 -0
  58. crca_llm/types.py +21 -0
  59. crca_reasoning/__init__.py +16 -0
  60. crca_reasoning/critique.py +54 -0
  61. crca_reasoning/godclass.py +206 -0
  62. crca_reasoning/memory.py +24 -0
  63. crca_reasoning/rationale.py +10 -0
  64. crca_reasoning/react_controller.py +81 -0
  65. crca_reasoning/tool_router.py +97 -0
  66. crca_reasoning/types.py +40 -0
  67. crca_sd/__init__.py +15 -0
  68. crca_sd/crca_sd_core.py +2 -0
  69. crca_sd/crca_sd_governance.py +2 -0
  70. crca_sd/crca_sd_mpc.py +2 -0
  71. crca_sd/crca_sd_realtime.py +2 -0
  72. crca_sd/crca_sd_tui.py +2 -0
  73. cuda-keyring_1.1-1_all.deb +0 -0
  74. cuda-keyring_1.1-1_all.deb.1 +0 -0
  75. docs/IMAGE_ANNOTATION_USAGE.md +539 -0
  76. docs/INSTALL_DEEPSPEED.md +125 -0
  77. docs/api/branches/crca-cg.md +19 -0
  78. docs/api/branches/crca-q.md +27 -0
  79. docs/api/branches/crca-sd.md +37 -0
  80. docs/api/branches/general-agent.md +24 -0
  81. docs/api/branches/overview.md +19 -0
  82. docs/api/crca/agent-methods.md +62 -0
  83. docs/api/crca/operations.md +79 -0
  84. docs/api/crca/overview.md +32 -0
  85. docs/api/image-annotation/engine.md +52 -0
  86. docs/api/image-annotation/overview.md +17 -0
  87. docs/api/schemas/annotation.md +34 -0
  88. docs/api/schemas/core-schemas.md +82 -0
  89. docs/api/schemas/overview.md +32 -0
  90. docs/api/schemas/policy.md +30 -0
  91. docs/api/utils/conversation.md +22 -0
  92. docs/api/utils/graph-reasoner.md +32 -0
  93. docs/api/utils/overview.md +21 -0
  94. docs/api/utils/router.md +19 -0
  95. docs/api/utils/utilities.md +97 -0
  96. docs/architecture/causal-graphs.md +41 -0
  97. docs/architecture/data-flow.md +29 -0
  98. docs/architecture/design-principles.md +33 -0
  99. docs/architecture/hybrid-agent/components.md +38 -0
  100. docs/architecture/hybrid-agent/consistency.md +26 -0
  101. docs/architecture/hybrid-agent/overview.md +44 -0
  102. docs/architecture/hybrid-agent/reasoning.md +22 -0
  103. docs/architecture/llm-integration.md +26 -0
  104. docs/architecture/modular-structure.md +37 -0
  105. docs/architecture/overview.md +69 -0
  106. docs/architecture/policy-engine-arch.md +29 -0
  107. docs/branches/crca-cg/corposwarm.md +39 -0
  108. docs/branches/crca-cg/esg-scoring.md +30 -0
  109. docs/branches/crca-cg/multi-agent.md +35 -0
  110. docs/branches/crca-cg/overview.md +40 -0
  111. docs/branches/crca-q/alternative-data.md +55 -0
  112. docs/branches/crca-q/architecture.md +71 -0
  113. docs/branches/crca-q/backtesting.md +45 -0
  114. docs/branches/crca-q/causal-engine.md +33 -0
  115. docs/branches/crca-q/execution.md +39 -0
  116. docs/branches/crca-q/market-data.md +60 -0
  117. docs/branches/crca-q/overview.md +58 -0
  118. docs/branches/crca-q/philosophy.md +60 -0
  119. docs/branches/crca-q/portfolio-optimization.md +66 -0
  120. docs/branches/crca-q/risk-management.md +102 -0
  121. docs/branches/crca-q/setup.md +65 -0
  122. docs/branches/crca-q/signal-generation.md +61 -0
  123. docs/branches/crca-q/signal-validation.md +43 -0
  124. docs/branches/crca-sd/core.md +84 -0
  125. docs/branches/crca-sd/governance.md +53 -0
  126. docs/branches/crca-sd/mpc-solver.md +65 -0
  127. docs/branches/crca-sd/overview.md +59 -0
  128. docs/branches/crca-sd/realtime.md +28 -0
  129. docs/branches/crca-sd/tui.md +20 -0
  130. docs/branches/general-agent/overview.md +37 -0
  131. docs/branches/general-agent/personality.md +36 -0
  132. docs/branches/general-agent/prompt-builder.md +30 -0
  133. docs/changelog/index.md +79 -0
  134. docs/contributing/code-style.md +69 -0
  135. docs/contributing/documentation.md +43 -0
  136. docs/contributing/overview.md +29 -0
  137. docs/contributing/testing.md +29 -0
  138. docs/core/crcagent/async-operations.md +65 -0
  139. docs/core/crcagent/automatic-extraction.md +107 -0
  140. docs/core/crcagent/batch-prediction.md +80 -0
  141. docs/core/crcagent/bayesian-inference.md +60 -0
  142. docs/core/crcagent/causal-graph.md +92 -0
  143. docs/core/crcagent/counterfactuals.md +96 -0
  144. docs/core/crcagent/deterministic-simulation.md +78 -0
  145. docs/core/crcagent/dual-mode-operation.md +82 -0
  146. docs/core/crcagent/initialization.md +88 -0
  147. docs/core/crcagent/optimization.md +65 -0
  148. docs/core/crcagent/overview.md +63 -0
  149. docs/core/crcagent/time-series.md +57 -0
  150. docs/core/schemas/annotation.md +30 -0
  151. docs/core/schemas/core-schemas.md +82 -0
  152. docs/core/schemas/overview.md +30 -0
  153. docs/core/schemas/policy.md +41 -0
  154. docs/core/templates/base-agent.md +31 -0
  155. docs/core/templates/feature-mixins.md +31 -0
  156. docs/core/templates/overview.md +29 -0
  157. docs/core/templates/templates-guide.md +75 -0
  158. docs/core/tools/mcp-client.md +34 -0
  159. docs/core/tools/overview.md +24 -0
  160. docs/core/utils/conversation.md +27 -0
  161. docs/core/utils/graph-reasoner.md +29 -0
  162. docs/core/utils/overview.md +27 -0
  163. docs/core/utils/router.md +27 -0
  164. docs/core/utils/utilities.md +97 -0
  165. docs/css/custom.css +84 -0
  166. docs/examples/basic-usage.md +57 -0
  167. docs/examples/general-agent/general-agent-examples.md +50 -0
  168. docs/examples/hybrid-agent/hybrid-agent-examples.md +56 -0
  169. docs/examples/image-annotation/image-annotation-examples.md +54 -0
  170. docs/examples/integration/integration-examples.md +58 -0
  171. docs/examples/overview.md +37 -0
  172. docs/examples/trading/trading-examples.md +46 -0
  173. docs/features/causal-reasoning/advanced-topics.md +101 -0
  174. docs/features/causal-reasoning/counterfactuals.md +43 -0
  175. docs/features/causal-reasoning/do-calculus.md +50 -0
  176. docs/features/causal-reasoning/overview.md +47 -0
  177. docs/features/causal-reasoning/structural-models.md +52 -0
  178. docs/features/hybrid-agent/advanced-components.md +55 -0
  179. docs/features/hybrid-agent/core-components.md +64 -0
  180. docs/features/hybrid-agent/overview.md +34 -0
  181. docs/features/image-annotation/engine.md +82 -0
  182. docs/features/image-annotation/features.md +113 -0
  183. docs/features/image-annotation/integration.md +75 -0
  184. docs/features/image-annotation/overview.md +53 -0
  185. docs/features/image-annotation/quickstart.md +73 -0
  186. docs/features/policy-engine/doctrine-ledger.md +105 -0
  187. docs/features/policy-engine/monitoring.md +44 -0
  188. docs/features/policy-engine/mpc-control.md +89 -0
  189. docs/features/policy-engine/overview.md +46 -0
  190. docs/getting-started/configuration.md +225 -0
  191. docs/getting-started/first-agent.md +164 -0
  192. docs/getting-started/installation.md +144 -0
  193. docs/getting-started/quickstart.md +137 -0
  194. docs/index.md +118 -0
  195. docs/js/mathjax.js +13 -0
  196. docs/lrm/discovery_proof_notes.md +25 -0
  197. docs/lrm/finetune_full.md +83 -0
  198. docs/lrm/math_appendix.md +120 -0
  199. docs/lrm/overview.md +32 -0
  200. docs/mkdocs.yml +238 -0
  201. docs/stylesheets/extra.css +21 -0
  202. docs_generated/crca_core/CounterfactualResult.md +12 -0
  203. docs_generated/crca_core/DiscoveryHypothesisResult.md +13 -0
  204. docs_generated/crca_core/DraftSpec.md +13 -0
  205. docs_generated/crca_core/EstimateResult.md +13 -0
  206. docs_generated/crca_core/IdentificationResult.md +17 -0
  207. docs_generated/crca_core/InterventionDesignResult.md +12 -0
  208. docs_generated/crca_core/LockedSpec.md +15 -0
  209. docs_generated/crca_core/RefusalResult.md +12 -0
  210. docs_generated/crca_core/ValidationReport.md +9 -0
  211. docs_generated/crca_core/index.md +13 -0
  212. examples/general_agent_example.py +277 -0
  213. examples/general_agent_quickstart.py +202 -0
  214. examples/general_agent_simple.py +92 -0
  215. examples/hybrid_agent_auto_extraction.py +84 -0
  216. examples/hybrid_agent_dictionary_demo.py +104 -0
  217. examples/hybrid_agent_enhanced.py +179 -0
  218. examples/hybrid_agent_general_knowledge.py +107 -0
  219. examples/image_annotation_quickstart.py +328 -0
  220. examples/test_hybrid_fixes.py +77 -0
  221. image_annotation/__init__.py +27 -0
  222. image_annotation/annotation_engine.py +2593 -0
  223. install_cuda_wsl2.sh +59 -0
  224. install_deepspeed.sh +56 -0
  225. install_deepspeed_simple.sh +87 -0
  226. mkdocs.yml +252 -0
  227. ollama/Modelfile +8 -0
  228. prompts/__init__.py +2 -1
  229. prompts/default_crca.py +9 -1
  230. prompts/general_agent.py +227 -0
  231. prompts/image_annotation.py +56 -0
  232. pyproject.toml +17 -2
  233. requirements-docs.txt +10 -0
  234. requirements.txt +21 -2
  235. schemas/__init__.py +26 -1
  236. schemas/annotation.py +222 -0
  237. schemas/conversation.py +193 -0
  238. schemas/hybrid.py +211 -0
  239. schemas/reasoning.py +276 -0
  240. schemas_export/crca_core/CounterfactualResult.schema.json +108 -0
  241. schemas_export/crca_core/DiscoveryHypothesisResult.schema.json +113 -0
  242. schemas_export/crca_core/DraftSpec.schema.json +635 -0
  243. schemas_export/crca_core/EstimateResult.schema.json +113 -0
  244. schemas_export/crca_core/IdentificationResult.schema.json +145 -0
  245. schemas_export/crca_core/InterventionDesignResult.schema.json +111 -0
  246. schemas_export/crca_core/LockedSpec.schema.json +646 -0
  247. schemas_export/crca_core/RefusalResult.schema.json +90 -0
  248. schemas_export/crca_core/ValidationReport.schema.json +62 -0
  249. scripts/build_lrm_dataset.py +80 -0
  250. scripts/export_crca_core_schemas.py +54 -0
  251. scripts/export_hf_lrm.py +37 -0
  252. scripts/export_ollama_gguf.py +45 -0
  253. scripts/generate_changelog.py +157 -0
  254. scripts/generate_crca_core_docs_from_schemas.py +86 -0
  255. scripts/run_crca_core_benchmarks.py +163 -0
  256. scripts/run_full_finetune.py +198 -0
  257. scripts/run_lrm_eval.py +31 -0
  258. templates/graph_management.py +29 -0
  259. tests/conftest.py +9 -0
  260. tests/test_core.py +2 -3
  261. tests/test_crca_core_discovery_tabular.py +15 -0
  262. tests/test_crca_core_estimate_dowhy.py +36 -0
  263. tests/test_crca_core_identify.py +18 -0
  264. tests/test_crca_core_intervention_design.py +36 -0
  265. tests/test_crca_core_linear_gaussian_scm.py +69 -0
  266. tests/test_crca_core_spec.py +25 -0
  267. tests/test_crca_core_timeseries_pcmci.py +15 -0
  268. tests/test_crca_llm_coauthor.py +12 -0
  269. tests/test_crca_llm_orchestrator.py +80 -0
  270. tests/test_hybrid_agent_llm_enhanced.py +556 -0
  271. tests/test_image_annotation_demo.py +376 -0
  272. tests/test_image_annotation_operational.py +408 -0
  273. tests/test_image_annotation_unit.py +551 -0
  274. tests/test_training_moe.py +13 -0
  275. training/__init__.py +42 -0
  276. training/datasets.py +140 -0
  277. training/deepspeed_zero2_0_5b.json +22 -0
  278. training/deepspeed_zero2_1_5b.json +22 -0
  279. training/deepspeed_zero3_0_5b.json +28 -0
  280. training/deepspeed_zero3_14b.json +28 -0
  281. training/deepspeed_zero3_h100_3gpu.json +20 -0
  282. training/deepspeed_zero3_offload.json +28 -0
  283. training/eval.py +92 -0
  284. training/finetune.py +516 -0
  285. training/public_datasets.py +89 -0
  286. training_data/react_train.jsonl +7473 -0
  287. utils/agent_discovery.py +311 -0
  288. utils/batch_processor.py +317 -0
  289. utils/conversation.py +78 -0
  290. utils/edit_distance.py +118 -0
  291. utils/formatter.py +33 -0
  292. utils/graph_reasoner.py +530 -0
  293. utils/rate_limiter.py +283 -0
  294. utils/router.py +2 -2
  295. utils/tool_discovery.py +307 -0
  296. webui/__init__.py +10 -0
  297. webui/app.py +229 -0
  298. webui/config.py +104 -0
  299. webui/static/css/style.css +332 -0
  300. webui/static/js/main.js +284 -0
  301. webui/templates/index.html +42 -0
  302. tests/test_crca_excel.py +0 -166
  303. tests/test_data_broker.py +0 -424
  304. tests/test_palantir.py +0 -349
  305. {crca-1.4.0.dist-info → crca-1.5.0.dist-info}/WHEEL +0 -0
  306. {crca-1.4.0.dist-info → crca-1.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,567 @@
1
+ """
2
+ Task Decomposition Engine with Hierarchical Planning and Dependency Resolution.
3
+
4
+ Implements HTN planning with dependency DAG resolution, parallel execution
5
+ with dataflow semantics, and fault tolerance.
6
+
7
+ Theoretical Basis:
8
+ - Hierarchical Task Networks (HTN) (Erol et al. 1994)
9
+ - STRIPS planning (Fikes & Nilsson 1971)
10
+ - Dependency Graphs (Tarjan 1972)
11
+ """
12
+
13
+ from typing import Dict, List, Optional, Tuple, Any, Set
14
+ from collections import defaultdict, deque
15
+ from enum import Enum
16
+ from dataclasses import dataclass, field
17
+ import logging
18
+ import re
19
+ import time
20
+ import uuid
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+
25
+ class TaskComplexity(Enum):
26
+ """Task complexity levels."""
27
+ SIMPLE = "simple"
28
+ MODERATE = "moderate"
29
+ COMPLEX = "complex"
30
+ VERY_COMPLEX = "very_complex"
31
+
32
+
33
+ class TaskStatus(Enum):
34
+ """Task execution status."""
35
+ PENDING = "pending"
36
+ READY = "ready"
37
+ RUNNING = "running"
38
+ COMPLETED = "completed"
39
+ FAILED = "failed"
40
+ SKIPPED = "skipped"
41
+
42
+
43
+ @dataclass
44
+ class SubTask:
45
+ """
46
+ Represents a subtask in the decomposition.
47
+
48
+ Attributes:
49
+ task_id: Unique task identifier
50
+ description: Task description
51
+ inputs: Required inputs
52
+ outputs: Expected outputs
53
+ dependencies: List of task IDs this task depends on
54
+ complexity: Estimated complexity
55
+ status: Current execution status
56
+ result: Task result (if completed)
57
+ error: Error message (if failed)
58
+ """
59
+ task_id: str
60
+ description: str
61
+ inputs: List[str] = field(default_factory=list)
62
+ outputs: List[str] = field(default_factory=list)
63
+ dependencies: List[str] = field(default_factory=list)
64
+ complexity: TaskComplexity = TaskComplexity.SIMPLE
65
+ status: TaskStatus = TaskStatus.PENDING
66
+ result: Optional[Any] = None
67
+ error: Optional[str] = None
68
+
69
+
70
+ class TaskAnalyzer:
71
+ """
72
+ Implements task complexity analysis and decomposition.
73
+
74
+ Features:
75
+ - Complexity detection using Kolmogorov complexity estimation
76
+ - Sub-task generation using decomposition rules
77
+ - Dependency analysis building dependency DAG
78
+ - Plan generation with topological ordering
79
+ """
80
+
81
+ def __init__(self):
82
+ """Initialize task analyzer."""
83
+ self.decomposition_rules: List[Dict[str, Any]] = []
84
+ self.complexity_threshold = 50 # Threshold for decomposition
85
+
86
+ def analyze_task(
87
+ self,
88
+ task: str
89
+ ) -> Tuple[TaskComplexity, bool]:
90
+ """
91
+ Analyze task complexity.
92
+
93
+ Uses Kolmogorov complexity estimation: K(task) ≈ length of compressed representation.
94
+
95
+ Args:
96
+ task: Task description
97
+
98
+ Returns:
99
+ Tuple of (complexity, should_decompose)
100
+ """
101
+ # Simple complexity estimation: length and keyword analysis
102
+ task_length = len(task)
103
+ complexity_keywords = [
104
+ 'analyze', 'compare', 'evaluate', 'synthesize', 'multiple',
105
+ 'complex', 'several', 'various', 'different'
106
+ ]
107
+
108
+ keyword_count = sum(1 for kw in complexity_keywords if kw in task.lower())
109
+
110
+ # Estimate complexity
111
+ if task_length < 50 and keyword_count == 0:
112
+ complexity = TaskComplexity.SIMPLE
113
+ should_decompose = False
114
+ elif task_length < 100 and keyword_count < 2:
115
+ complexity = TaskComplexity.MODERATE
116
+ should_decompose = False
117
+ elif task_length < 200 or keyword_count >= 2:
118
+ complexity = TaskComplexity.COMPLEX
119
+ should_decompose = True
120
+ else:
121
+ complexity = TaskComplexity.VERY_COMPLEX
122
+ should_decompose = True
123
+
124
+ return complexity, should_decompose
125
+
126
+ def decompose_task(
127
+ self,
128
+ task: str,
129
+ decomposition_rules: Optional[List[Dict[str, Any]]] = None
130
+ ) -> List[SubTask]:
131
+ """
132
+ Decompose task into subtasks.
133
+
134
+ Algorithm:
135
+ function decompose_task(task):
136
+ if is_primitive(task):
137
+ return [task]
138
+ decomposition_rules = get_applicable_rules(task)
139
+ best_rule = argmin(rule.complexity for rule in decomposition_rules)
140
+ subtasks = apply_decomposition(best_rule, task)
141
+ return [decompose_task(t) for t in subtasks].flatten()
142
+
143
+ Args:
144
+ task: Task to decompose
145
+ decomposition_rules: Optional decomposition rules
146
+
147
+ Returns:
148
+ List of subtasks
149
+ """
150
+ if decomposition_rules is None:
151
+ decomposition_rules = self._get_default_rules()
152
+
153
+ # Check if task is primitive (simple enough)
154
+ complexity, should_decompose = self.analyze_task(task)
155
+ if not should_decompose:
156
+ # Return as single primitive task
157
+ return [SubTask(
158
+ task_id=f"task_{int(time.time() * 1000)}",
159
+ description=task,
160
+ complexity=complexity
161
+ )]
162
+
163
+ # Apply decomposition rules
164
+ applicable_rules = self._get_applicable_rules(task, decomposition_rules)
165
+ if not applicable_rules:
166
+ # No applicable rules, return as single task
167
+ return [SubTask(
168
+ task_id=f"task_{int(time.time() * 1000)}",
169
+ description=task,
170
+ complexity=complexity
171
+ )]
172
+
173
+ # Select best rule (lowest complexity)
174
+ best_rule = min(applicable_rules, key=lambda r: r.get('complexity', 100))
175
+
176
+ # Apply decomposition
177
+ subtasks = self._apply_decomposition(task, best_rule)
178
+
179
+ # Recursively decompose subtasks
180
+ all_subtasks = []
181
+ for subtask_desc in subtasks:
182
+ sub_subtasks = self.decompose_task(subtask_desc, decomposition_rules)
183
+ all_subtasks.extend(sub_subtasks)
184
+
185
+ return all_subtasks
186
+
187
+ def _get_default_rules(self) -> List[Dict[str, Any]]:
188
+ """Get default decomposition rules."""
189
+ return [
190
+ {
191
+ 'pattern': r'analyze\s+(.+?)\s+and\s+(.+?)',
192
+ 'decomposition': ['analyze {0}', 'analyze {1}'],
193
+ 'complexity': 2
194
+ },
195
+ {
196
+ 'pattern': r'compare\s+(.+?)\s+with\s+(.+?)',
197
+ 'decomposition': ['analyze {0}', 'analyze {1}', 'compare results'],
198
+ 'complexity': 3
199
+ },
200
+ {
201
+ 'pattern': r'(.+?)\s+then\s+(.+?)',
202
+ 'decomposition': ['{0}', '{1}'],
203
+ 'complexity': 2
204
+ }
205
+ ]
206
+
207
+ def _get_applicable_rules(
208
+ self,
209
+ task: str,
210
+ rules: List[Dict[str, Any]]
211
+ ) -> List[Dict[str, Any]]:
212
+ """Get applicable decomposition rules."""
213
+ applicable = []
214
+ for rule in rules:
215
+ pattern = rule.get('pattern', '')
216
+ if pattern and re.search(pattern, task, re.IGNORECASE):
217
+ applicable.append(rule)
218
+ return applicable
219
+
220
+ def _apply_decomposition(
221
+ self,
222
+ task: str,
223
+ rule: Dict[str, Any]
224
+ ) -> List[str]:
225
+ """Apply decomposition rule to task."""
226
+ pattern = rule.get('pattern', '')
227
+ decomposition = rule.get('decomposition', [])
228
+
229
+ match = re.search(pattern, task, re.IGNORECASE)
230
+ if not match:
231
+ return [task]
232
+
233
+ # Substitute matched groups
234
+ subtasks = []
235
+ for subtask_template in decomposition:
236
+ subtask = subtask_template
237
+ for i, group in enumerate(match.groups()):
238
+ subtask = subtask.replace(f'{{{i}}}', group)
239
+ subtasks.append(subtask)
240
+
241
+ return subtasks if subtasks else [task]
242
+
243
+ def build_dependency_graph(
244
+ self,
245
+ subtasks: List[SubTask]
246
+ ) -> Dict[str, List[str]]:
247
+ """
248
+ Build dependency DAG from subtasks.
249
+
250
+ D = (T, E_dep) where (Tᵢ, Tⱼ) ∈ E_dep means Tᵢ must precede Tⱼ.
251
+
252
+ O(n²) complexity for dependency analysis.
253
+
254
+ Args:
255
+ subtasks: List of subtasks
256
+
257
+ Returns:
258
+ Dictionary mapping task_id to list of dependent task IDs
259
+ """
260
+ dependencies: Dict[str, List[str]] = defaultdict(list)
261
+
262
+ # Build task index
263
+ task_index = {task.task_id: task for task in subtasks}
264
+
265
+ # Analyze dependencies based on inputs/outputs
266
+ for task in subtasks:
267
+ for other_task in subtasks:
268
+ if task.task_id == other_task.task_id:
269
+ continue
270
+
271
+ # Check if other_task's outputs match task's inputs
272
+ if any(output in task.inputs for output in other_task.outputs):
273
+ dependencies[task.task_id].append(other_task.task_id)
274
+
275
+ return dict(dependencies)
276
+
277
+ def generate_execution_plan(
278
+ self,
279
+ subtasks: List[SubTask],
280
+ dependencies: Dict[str, List[str]]
281
+ ) -> List[str]:
282
+ """
283
+ Generate execution plan respecting topological ordering.
284
+
285
+ O(n log n) complexity for topological sort.
286
+
287
+ Args:
288
+ subtasks: List of subtasks
289
+ dependencies: Dependency graph
290
+
291
+ Returns:
292
+ List of task IDs in execution order
293
+ """
294
+ # Kahn's algorithm for topological sort
295
+ in_degree: Dict[str, int] = defaultdict(int)
296
+ task_ids = {task.task_id for task in subtasks}
297
+
298
+ # Initialize in-degrees
299
+ for task_id in task_ids:
300
+ in_degree[task_id] = 0
301
+
302
+ # Count in-degrees
303
+ for task_id, deps in dependencies.items():
304
+ for dep in deps:
305
+ in_degree[dep] += 1
306
+
307
+ # Find tasks with no dependencies
308
+ queue = deque([task_id for task_id in task_ids if in_degree[task_id] == 0])
309
+ execution_order = []
310
+
311
+ while queue:
312
+ task_id = queue.popleft()
313
+ execution_order.append(task_id)
314
+
315
+ # Reduce in-degree of dependent tasks
316
+ for dep in dependencies.get(task_id, []):
317
+ in_degree[dep] -= 1
318
+ if in_degree[dep] == 0:
319
+ queue.append(dep)
320
+
321
+ # Check for cycles (if not all tasks in execution order)
322
+ if len(execution_order) < len(task_ids):
323
+ logger.warning("Circular dependencies detected in task graph")
324
+ # Add remaining tasks (may have cycles)
325
+ remaining = task_ids - set(execution_order)
326
+ execution_order.extend(remaining)
327
+
328
+ return execution_order
329
+
330
+
331
+ class SubTaskExecutor:
332
+ """
333
+ Implements parallel execution with dependency resolution and fault tolerance.
334
+
335
+ Features:
336
+ - Topological sort execution order
337
+ - Dataflow execution semantics
338
+ - Result aggregation
339
+ - Partial failure handling with rollback
340
+ """
341
+
342
+ def __init__(self):
343
+ """Initialize subtask executor."""
344
+ self.execution_results: Dict[str, Any] = {}
345
+ self.execution_history: List[Dict[str, Any]] = []
346
+
347
+ def execute_plan(
348
+ self,
349
+ subtasks: List[SubTask],
350
+ execution_order: List[str],
351
+ dependencies: Dict[str, List[str]],
352
+ executor_func: Optional[callable] = None
353
+ ) -> Dict[str, Any]:
354
+ """
355
+ Execute plan with dependency resolution.
356
+
357
+ Algorithm:
358
+ function execute_plan(plan, dependencies):
359
+ execution_order = topological_sort(plan, dependencies)
360
+ results = {}
361
+ for task in execution_order:
362
+ inputs = [results[dep] for dep in dependencies[task]]
363
+ results[task] = execute(task, inputs)
364
+ return aggregate(results)
365
+
366
+ Args:
367
+ subtasks: List of subtasks
368
+ execution_order: Execution order (topological sort)
369
+ dependencies: Dependency graph
370
+ executor_func: Optional function to execute tasks
371
+
372
+ Returns:
373
+ Aggregated results
374
+ """
375
+ task_index = {task.task_id: task for task in subtasks}
376
+ results = {}
377
+ failed_tasks = set()
378
+
379
+ for task_id in execution_order:
380
+ task = task_index.get(task_id)
381
+ if not task:
382
+ continue
383
+
384
+ # Check if dependencies are ready
385
+ deps = dependencies.get(task_id, [])
386
+ if any(dep in failed_tasks for dep in deps):
387
+ # Dependency failed, skip this task
388
+ task.status = TaskStatus.SKIPPED
389
+ task.error = "Dependency failed"
390
+ continue
391
+
392
+ # Get inputs from dependencies
393
+ inputs = [results.get(dep) for dep in deps]
394
+
395
+ # Execute task
396
+ try:
397
+ task.status = TaskStatus.RUNNING
398
+ if executor_func:
399
+ result = executor_func(task, inputs)
400
+ else:
401
+ result = self._default_execute(task, inputs)
402
+
403
+ task.result = result
404
+ task.status = TaskStatus.COMPLETED
405
+ results[task_id] = result
406
+
407
+ except Exception as e:
408
+ task.status = TaskStatus.FAILED
409
+ task.error = str(e)
410
+ failed_tasks.add(task_id)
411
+
412
+ # Rollback dependent tasks
413
+ self._rollback_dependents(task_id, dependencies, task_index)
414
+
415
+ # Aggregate results
416
+ return self._aggregate_results(results, subtasks)
417
+
418
+ def _default_execute(
419
+ self,
420
+ task: SubTask,
421
+ inputs: List[Any]
422
+ ) -> Any:
423
+ """
424
+ Default task execution (placeholder).
425
+
426
+ Args:
427
+ task: Task to execute
428
+ inputs: Input values from dependencies
429
+
430
+ Returns:
431
+ Task result
432
+ """
433
+ # Placeholder: return task description
434
+ return {
435
+ 'task_id': task.task_id,
436
+ 'description': task.description,
437
+ 'inputs': inputs,
438
+ 'status': 'completed'
439
+ }
440
+
441
+ def _rollback_dependents(
442
+ self,
443
+ failed_task_id: str,
444
+ dependencies: Dict[str, List[str]],
445
+ task_index: Dict[str, SubTask]
446
+ ) -> None:
447
+ """
448
+ Rollback tasks that depend on failed task.
449
+
450
+ Args:
451
+ failed_task_id: ID of failed task
452
+ dependencies: Dependency graph
453
+ task_index: Task index
454
+ """
455
+ # Find tasks that depend on failed task
456
+ for task_id, deps in dependencies.items():
457
+ if failed_task_id in deps:
458
+ task = task_index.get(task_id)
459
+ if task and task.status == TaskStatus.RUNNING:
460
+ task.status = TaskStatus.FAILED
461
+ task.error = f"Dependency {failed_task_id} failed"
462
+
463
+ def _aggregate_results(
464
+ self,
465
+ results: Dict[str, Any],
466
+ subtasks: List[SubTask]
467
+ ) -> Dict[str, Any]:
468
+ """
469
+ Aggregate results from all subtasks.
470
+
471
+ Args:
472
+ results: Dictionary of task results
473
+ subtasks: List of subtasks
474
+
475
+ Returns:
476
+ Aggregated results
477
+ """
478
+ return {
479
+ 'results': results,
480
+ 'completed_tasks': [t.task_id for t in subtasks if t.status == TaskStatus.COMPLETED],
481
+ 'failed_tasks': [t.task_id for t in subtasks if t.status == TaskStatus.FAILED],
482
+ 'skipped_tasks': [t.task_id for t in subtasks if t.status == TaskStatus.SKIPPED],
483
+ 'total_tasks': len(subtasks)
484
+ }
485
+
486
+
487
+ class PlanGenerator:
488
+ """
489
+ Implements optimal planning with complexity estimation.
490
+
491
+ Features:
492
+ - Step-by-step plan generation
493
+ - Complexity estimation
494
+ - Information requirement identification
495
+ - Intermediate step suggestion
496
+ """
497
+
498
+ def __init__(self, task_analyzer: TaskAnalyzer):
499
+ """
500
+ Initialize plan generator.
501
+
502
+ Args:
503
+ task_analyzer: TaskAnalyzer instance
504
+ """
505
+ self.task_analyzer = task_analyzer
506
+
507
+ def generate_plan(
508
+ self,
509
+ task: str
510
+ ) -> Dict[str, Any]:
511
+ """
512
+ Generate execution plan for task.
513
+
514
+ Args:
515
+ task: Task description
516
+
517
+ Returns:
518
+ Plan dictionary with subtasks, dependencies, execution order
519
+ """
520
+ # Decompose task
521
+ subtasks = self.task_analyzer.decompose_task(task)
522
+
523
+ # Build dependency graph
524
+ dependencies = self.task_analyzer.build_dependency_graph(subtasks)
525
+
526
+ # Generate execution order
527
+ execution_order = self.task_analyzer.generate_execution_plan(subtasks, dependencies)
528
+
529
+ # Estimate complexity
530
+ total_complexity = sum(
531
+ self._estimate_complexity(t.description) for t in subtasks
532
+ )
533
+
534
+ # Identify information requirements
535
+ required_inputs = self._identify_required_inputs(subtasks, dependencies)
536
+
537
+ return {
538
+ 'task': task,
539
+ 'subtasks': subtasks,
540
+ 'dependencies': dependencies,
541
+ 'execution_order': execution_order,
542
+ 'total_complexity': total_complexity,
543
+ 'required_inputs': required_inputs,
544
+ 'estimated_steps': len(subtasks)
545
+ }
546
+
547
+ def _estimate_complexity(self, task_description: str) -> int:
548
+ """Estimate computational complexity of task."""
549
+ # Simple estimation based on length and keywords
550
+ length = len(task_description)
551
+ complexity_keywords = ['analyze', 'compare', 'evaluate', 'synthesize']
552
+ keyword_count = sum(1 for kw in complexity_keywords if kw in task_description.lower())
553
+
554
+ return length // 10 + keyword_count * 5
555
+
556
+ def _identify_required_inputs(
557
+ self,
558
+ subtasks: List[SubTask],
559
+ dependencies: Dict[str, List[str]]
560
+ ) -> Set[str]:
561
+ """Identify required inputs for all subtasks."""
562
+ required = set()
563
+ for task in subtasks:
564
+ # Tasks with no dependencies need external inputs
565
+ if task.task_id not in dependencies or not dependencies[task.task_id]:
566
+ required.update(task.inputs)
567
+ return required