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,286 @@
1
+ """
2
+ Graph compression and abstraction module.
3
+
4
+ Provides functionality for creating composite nodes, latent factors,
5
+ and graph simplification through abstraction.
6
+ """
7
+
8
+ from typing import Dict, List, Optional, Set, Any
9
+ import logging
10
+
11
+ from templates.graph_management import GraphManager
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class GraphCompressor:
17
+ """
18
+ Compresses and abstracts causal graphs through composite nodes and latent factors.
19
+
20
+ Features:
21
+ - Composite node creation (multiple variables → single node)
22
+ - Latent factor abstraction
23
+ - Graph simplification (remove low-confidence edges, merge redundant paths)
24
+ - Hierarchical structure creation
25
+ """
26
+
27
+ def __init__(self, graph_manager: GraphManager):
28
+ """
29
+ Initialize graph compressor.
30
+
31
+ Args:
32
+ graph_manager: GraphManager instance to compress
33
+ """
34
+ self.graph_manager = graph_manager
35
+ self.composite_nodes: Dict[str, List[str]] = {} # composite_name -> [original_nodes]
36
+ self.latent_factors: Dict[str, List[str]] = {} # latent_name -> [observed_nodes]
37
+
38
+ def create_composite_node(
39
+ self,
40
+ variables: List[str],
41
+ name: str,
42
+ preserve_originals: bool = True
43
+ ) -> str:
44
+ """
45
+ Create a composite node from multiple variables.
46
+
47
+ Example: "product quality" + "service quality" → "quality_factor"
48
+
49
+ Args:
50
+ variables: List of variable names to combine
51
+ name: Name for the composite node
52
+ preserve_originals: Whether to keep original nodes in graph
53
+
54
+ Returns:
55
+ Name of the created composite node
56
+ """
57
+ # Validate variables exist
58
+ for var in variables:
59
+ if var not in self.graph_manager.get_nodes():
60
+ logger.warning(f"Variable {var} not in graph, skipping composite creation")
61
+ return name
62
+
63
+ # Store composite mapping
64
+ self.composite_nodes[name] = variables.copy()
65
+
66
+ # Ensure composite node exists
67
+ self.graph_manager.ensure_node_exists(name)
68
+
69
+ # Aggregate edges from original variables
70
+ # Incoming edges: union of all incoming edges from original variables
71
+ incoming_sources: Set[str] = set()
72
+ for var in variables:
73
+ parents = self.graph_manager.get_parents(var)
74
+ incoming_sources.update(parents)
75
+
76
+ for source in incoming_sources:
77
+ # Aggregate strength from all original variables
78
+ total_strength = 0.0
79
+ count = 0
80
+ for var in variables:
81
+ strength = self.graph_manager.edge_strength(source, var)
82
+ if strength > 0:
83
+ total_strength += strength
84
+ count += 1
85
+
86
+ if count > 0:
87
+ avg_strength = total_strength / count
88
+ self.graph_manager.add_relationship(
89
+ source, name,
90
+ strength=avg_strength,
91
+ relation_type="composite_incoming"
92
+ )
93
+
94
+ # Outgoing edges: union of all outgoing edges from original variables
95
+ outgoing_targets: Set[str] = set()
96
+ for var in variables:
97
+ children = self.graph_manager.get_children(var)
98
+ outgoing_targets.update(children)
99
+
100
+ for target in outgoing_targets:
101
+ # Aggregate strength from all original variables
102
+ total_strength = 0.0
103
+ count = 0
104
+ for var in variables:
105
+ strength = self.graph_manager.edge_strength(var, target)
106
+ if strength > 0:
107
+ total_strength += strength
108
+ count += 1
109
+
110
+ if count > 0:
111
+ avg_strength = total_strength / count
112
+ self.graph_manager.add_relationship(
113
+ name, target,
114
+ strength=avg_strength,
115
+ relation_type="composite_outgoing"
116
+ )
117
+
118
+ # Optionally remove original nodes
119
+ if not preserve_originals:
120
+ for var in variables:
121
+ # Remove all edges involving this variable
122
+ children = self.graph_manager.get_children(var)
123
+ for child in children:
124
+ # Edge removal would need to be added to GraphManager
125
+ pass
126
+ parents = self.graph_manager.get_parents(var)
127
+ for parent in parents:
128
+ # Edge removal would need to be added to GraphManager
129
+ pass
130
+
131
+ return name
132
+
133
+ def abstract_to_latent(self, variables: List[str], latent_name: Optional[str] = None) -> str:
134
+ """
135
+ Abstract multiple observed variables into a latent factor.
136
+
137
+ Example: "product quality", "service quality" → "quality_factor" (latent)
138
+
139
+ Args:
140
+ variables: List of observed variable names
141
+ latent_name: Name for latent factor (auto-generated if None)
142
+
143
+ Returns:
144
+ Name of the created latent factor
145
+ """
146
+ if latent_name is None:
147
+ latent_name = f"latent_{len(self.latent_factors)}"
148
+
149
+ # Store latent mapping
150
+ self.latent_factors[latent_name] = variables.copy()
151
+
152
+ # Ensure latent node exists
153
+ self.graph_manager.ensure_node_exists(latent_name)
154
+
155
+ # Create edges: latent → observed (latent causes observed)
156
+ for var in variables:
157
+ self.graph_manager.add_relationship(
158
+ latent_name, var,
159
+ strength=1.0,
160
+ relation_type="latent_to_observed"
161
+ )
162
+
163
+ # Inherit incoming edges from observed variables
164
+ incoming_sources: Set[str] = set()
165
+ for var in variables:
166
+ parents = self.graph_manager.get_parents(var)
167
+ incoming_sources.update(parents)
168
+
169
+ for source in incoming_sources:
170
+ if source not in variables: # Don't create self-loops
171
+ total_strength = 0.0
172
+ count = 0
173
+ for var in variables:
174
+ strength = self.graph_manager.edge_strength(source, var)
175
+ if strength > 0:
176
+ total_strength += strength
177
+ count += 1
178
+
179
+ if count > 0:
180
+ avg_strength = total_strength / count
181
+ self.graph_manager.add_relationship(
182
+ source, latent_name,
183
+ strength=avg_strength,
184
+ relation_type="latent_incoming"
185
+ )
186
+
187
+ return latent_name
188
+
189
+ def compress_subgraph(self, nodes: List[str]) -> Dict[str, Any]:
190
+ """
191
+ Compress a subgraph by removing low-confidence edges and merging redundant paths.
192
+
193
+ Args:
194
+ nodes: List of nodes in the subgraph to compress
195
+
196
+ Returns:
197
+ Dictionary with compression statistics
198
+ """
199
+ removed_edges = 0
200
+ merged_paths = 0
201
+
202
+ # Remove low-confidence edges (confidence < 0.3)
203
+ edges_to_remove = []
204
+ for source in nodes:
205
+ if source not in self.graph_manager.graph:
206
+ continue
207
+ for target, meta in self.graph_manager.graph[source].items():
208
+ if target not in nodes:
209
+ continue
210
+ if isinstance(meta, dict):
211
+ confidence = meta.get("confidence", 1.0)
212
+ if confidence < 0.3:
213
+ edges_to_remove.append((source, target))
214
+
215
+ # Note: Edge removal would need to be implemented in GraphManager
216
+ removed_edges = len(edges_to_remove)
217
+
218
+ # Merge redundant paths (simplified: detect and mark for merging)
219
+ # In a full implementation, would identify paths with same source/target
220
+ # and merge them into a single edge with aggregated strength
221
+
222
+ return {
223
+ "removed_edges": removed_edges,
224
+ "merged_paths": merged_paths,
225
+ "original_nodes": len(nodes),
226
+ "compressed_nodes": len(nodes) # Would be reduced in full implementation
227
+ }
228
+
229
+ def simplify_graph(
230
+ self,
231
+ min_confidence: float = 0.3,
232
+ min_strength: float = 0.1
233
+ ) -> Dict[str, Any]:
234
+ """
235
+ Simplify entire graph by removing low-confidence/strength edges.
236
+
237
+ Args:
238
+ min_confidence: Minimum confidence threshold
239
+ min_strength: Minimum strength threshold
240
+
241
+ Returns:
242
+ Dictionary with simplification statistics
243
+ """
244
+ all_nodes = self.graph_manager.get_nodes()
245
+ removed_edges = 0
246
+
247
+ edges_to_remove = []
248
+ for source in all_nodes:
249
+ if source not in self.graph_manager.graph:
250
+ continue
251
+ for target, meta in self.graph_manager.graph[source].items():
252
+ if isinstance(meta, dict):
253
+ confidence = meta.get("confidence", 1.0)
254
+ strength = meta.get("strength", 1.0)
255
+ if confidence < min_confidence or strength < min_strength:
256
+ edges_to_remove.append((source, target))
257
+
258
+ removed_edges = len(edges_to_remove)
259
+
260
+ # Note: Actual edge removal would need GraphManager.remove_edge method
261
+ # For now, just return statistics
262
+
263
+ return {
264
+ "removed_edges": removed_edges,
265
+ "remaining_nodes": len(all_nodes),
266
+ "min_confidence": min_confidence,
267
+ "min_strength": min_strength
268
+ }
269
+
270
+ def get_composite_mapping(self) -> Dict[str, List[str]]:
271
+ """
272
+ Get mapping of composite nodes to original variables.
273
+
274
+ Returns:
275
+ Dictionary mapping composite node names to lists of original variables
276
+ """
277
+ return self.composite_nodes.copy()
278
+
279
+ def get_latent_mapping(self) -> Dict[str, List[str]]:
280
+ """
281
+ Get mapping of latent factors to observed variables.
282
+
283
+ Returns:
284
+ Dictionary mapping latent factor names to lists of observed variables
285
+ """
286
+ return self.latent_factors.copy()