quantumflow-sdk 0.2.1__py3-none-any.whl → 0.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.
- api/main.py +34 -3
- api/models.py +41 -0
- api/routes/algorithm_routes.py +1029 -0
- api/routes/chat_routes.py +565 -0
- api/routes/pipeline_routes.py +578 -0
- db/models.py +357 -0
- quantumflow/algorithms/machine_learning/__init__.py +14 -2
- quantumflow/algorithms/machine_learning/vqe.py +355 -3
- quantumflow/core/__init__.py +10 -1
- quantumflow/core/quantum_compressor.py +379 -1
- quantumflow/integrations/domain_agents.py +617 -0
- quantumflow/pipeline/__init__.py +29 -0
- quantumflow/pipeline/anomaly_detector.py +521 -0
- quantumflow/pipeline/base_pipeline.py +602 -0
- quantumflow/pipeline/checkpoint_manager.py +587 -0
- quantumflow/pipeline/finance/__init__.py +5 -0
- quantumflow/pipeline/finance/portfolio_optimization.py +595 -0
- quantumflow/pipeline/healthcare/__init__.py +5 -0
- quantumflow/pipeline/healthcare/protein_folding.py +994 -0
- quantumflow/pipeline/temporal_memory.py +577 -0
- {quantumflow_sdk-0.2.1.dist-info → quantumflow_sdk-0.4.0.dist-info}/METADATA +3 -3
- {quantumflow_sdk-0.2.1.dist-info → quantumflow_sdk-0.4.0.dist-info}/RECORD +25 -12
- {quantumflow_sdk-0.2.1.dist-info → quantumflow_sdk-0.4.0.dist-info}/WHEEL +0 -0
- {quantumflow_sdk-0.2.1.dist-info → quantumflow_sdk-0.4.0.dist-info}/entry_points.txt +0 -0
- {quantumflow_sdk-0.2.1.dist-info → quantumflow_sdk-0.4.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,617 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Domain-Specific Quantum Agents for CrewAI.
|
|
3
|
+
|
|
4
|
+
Provides specialized agents for:
|
|
5
|
+
- Healthcare: Protein folding, drug discovery, mutation benchmarking
|
|
6
|
+
- Finance: Portfolio optimization, risk analysis, regime detection
|
|
7
|
+
|
|
8
|
+
Example:
|
|
9
|
+
from quantumflow.integrations.domain_agents import (
|
|
10
|
+
QuantumHealthcareAgent,
|
|
11
|
+
QuantumFinanceAgent,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
# Create healthcare agent
|
|
15
|
+
health_agent = QuantumHealthcareAgent.create(llm=my_llm)
|
|
16
|
+
result = health_agent.execute(task)
|
|
17
|
+
|
|
18
|
+
# Create finance agent
|
|
19
|
+
finance_agent = QuantumFinanceAgent.create(llm=my_llm)
|
|
20
|
+
result = finance_agent.execute(task)
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import logging
|
|
24
|
+
from typing import Any, Dict, List, Optional, Type
|
|
25
|
+
from dataclasses import dataclass
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
# Check for CrewAI availability
|
|
30
|
+
try:
|
|
31
|
+
from crewai import Agent, Task, Crew
|
|
32
|
+
from crewai.tools import BaseTool
|
|
33
|
+
CREWAI_AVAILABLE = True
|
|
34
|
+
except ImportError:
|
|
35
|
+
CREWAI_AVAILABLE = False
|
|
36
|
+
logger.warning("CrewAI not installed. Domain agents will be limited.")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# ============================================================
|
|
40
|
+
# Healthcare Tools
|
|
41
|
+
# ============================================================
|
|
42
|
+
|
|
43
|
+
if CREWAI_AVAILABLE:
|
|
44
|
+
|
|
45
|
+
class ProteinFoldingTool(BaseTool):
|
|
46
|
+
"""Tool for protein folding simulation using VQE."""
|
|
47
|
+
|
|
48
|
+
name: str = "protein_folding"
|
|
49
|
+
description: str = """
|
|
50
|
+
Simulate protein folding using quantum VQE algorithm.
|
|
51
|
+
Input: JSON with 'sequence' (amino acid sequence) and optional 'steps' (default 50).
|
|
52
|
+
Returns: Folding results including final energy and RMSD.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def _run(self, input_data: str) -> str:
|
|
56
|
+
"""Execute protein folding."""
|
|
57
|
+
import json
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
data = json.loads(input_data) if isinstance(input_data, str) else input_data
|
|
61
|
+
sequence = data.get("sequence", "MVLSPAD")
|
|
62
|
+
steps = data.get("steps", 50)
|
|
63
|
+
|
|
64
|
+
from quantumflow.pipeline.healthcare.protein_folding import (
|
|
65
|
+
ProteinFoldingPipeline,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
pipeline = ProteinFoldingPipeline(
|
|
69
|
+
name="Agent Protein Folding",
|
|
70
|
+
sequence=sequence,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
result = pipeline.run(total_steps=steps)
|
|
74
|
+
|
|
75
|
+
return json.dumps({
|
|
76
|
+
"status": result.status,
|
|
77
|
+
"final_energy": result.final_state.metrics.get("energy"),
|
|
78
|
+
"final_rmsd": result.final_state.metrics.get("rmsd"),
|
|
79
|
+
"steps_completed": result.total_steps,
|
|
80
|
+
"anomalies_detected": result.anomalies_detected,
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
except Exception as e:
|
|
84
|
+
return json.dumps({"error": str(e)})
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class MutationBenchmarkTool(BaseTool):
|
|
88
|
+
"""Tool for benchmarking protein mutations."""
|
|
89
|
+
|
|
90
|
+
name: str = "mutation_benchmark"
|
|
91
|
+
description: str = """
|
|
92
|
+
Benchmark the effect of mutations on protein stability.
|
|
93
|
+
Input: JSON with 'original_sequence', 'mutated_sequence', and optional 'steps'.
|
|
94
|
+
Returns: Comparison of energy and stability metrics.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
def _run(self, input_data: str) -> str:
|
|
98
|
+
"""Execute mutation benchmark."""
|
|
99
|
+
import json
|
|
100
|
+
|
|
101
|
+
try:
|
|
102
|
+
data = json.loads(input_data) if isinstance(input_data, str) else input_data
|
|
103
|
+
original = data.get("original_sequence", "MVLSPAD")
|
|
104
|
+
mutated = data.get("mutated_sequence", "MVLSAAD")
|
|
105
|
+
steps = data.get("steps", 30)
|
|
106
|
+
|
|
107
|
+
from quantumflow.pipeline.healthcare.protein_folding import (
|
|
108
|
+
ProteinFoldingPipeline,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# Run original
|
|
112
|
+
original_pipeline = ProteinFoldingPipeline(
|
|
113
|
+
name="Original",
|
|
114
|
+
sequence=original,
|
|
115
|
+
)
|
|
116
|
+
original_result = original_pipeline.run(total_steps=steps)
|
|
117
|
+
|
|
118
|
+
# Run mutated
|
|
119
|
+
mutated_pipeline = ProteinFoldingPipeline(
|
|
120
|
+
name="Mutated",
|
|
121
|
+
sequence=mutated,
|
|
122
|
+
)
|
|
123
|
+
mutated_result = mutated_pipeline.run(total_steps=steps)
|
|
124
|
+
|
|
125
|
+
original_energy = original_result.final_state.metrics.get("energy", 0)
|
|
126
|
+
mutated_energy = mutated_result.final_state.metrics.get("energy", 0)
|
|
127
|
+
|
|
128
|
+
return json.dumps({
|
|
129
|
+
"original": {
|
|
130
|
+
"sequence": original,
|
|
131
|
+
"final_energy": original_energy,
|
|
132
|
+
"rmsd": original_result.final_state.metrics.get("rmsd"),
|
|
133
|
+
},
|
|
134
|
+
"mutated": {
|
|
135
|
+
"sequence": mutated,
|
|
136
|
+
"final_energy": mutated_energy,
|
|
137
|
+
"rmsd": mutated_result.final_state.metrics.get("rmsd"),
|
|
138
|
+
},
|
|
139
|
+
"energy_difference": mutated_energy - original_energy,
|
|
140
|
+
"stability_impact": "destabilizing" if mutated_energy > original_energy else "stabilizing",
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
except Exception as e:
|
|
144
|
+
return json.dumps({"error": str(e)})
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class DrugBindingTool(BaseTool):
|
|
148
|
+
"""Tool for analyzing drug-protein binding."""
|
|
149
|
+
|
|
150
|
+
name: str = "drug_binding"
|
|
151
|
+
description: str = """
|
|
152
|
+
Analyze potential drug binding to a protein target.
|
|
153
|
+
Input: JSON with 'protein_sequence' and 'ligand_smiles'.
|
|
154
|
+
Returns: Binding affinity estimate and interaction analysis.
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
def _run(self, input_data: str) -> str:
|
|
158
|
+
"""Execute drug binding analysis."""
|
|
159
|
+
import json
|
|
160
|
+
import random
|
|
161
|
+
|
|
162
|
+
try:
|
|
163
|
+
data = json.loads(input_data) if isinstance(input_data, str) else input_data
|
|
164
|
+
protein = data.get("protein_sequence", "MVLSPAD")
|
|
165
|
+
ligand = data.get("ligand_smiles", "CC(=O)O")
|
|
166
|
+
|
|
167
|
+
# Simplified binding analysis (would use quantum docking in production)
|
|
168
|
+
binding_energy = -random.uniform(5, 15) # kcal/mol
|
|
169
|
+
binding_probability = random.uniform(0.3, 0.9)
|
|
170
|
+
|
|
171
|
+
return json.dumps({
|
|
172
|
+
"protein_length": len(protein),
|
|
173
|
+
"ligand": ligand,
|
|
174
|
+
"estimated_binding_energy_kcal": round(binding_energy, 2),
|
|
175
|
+
"binding_probability": round(binding_probability, 3),
|
|
176
|
+
"interaction_type": "hydrogen_bond" if binding_energy < -10 else "van_der_waals",
|
|
177
|
+
"recommendation": "promising" if binding_energy < -8 else "weak_binding",
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
except Exception as e:
|
|
181
|
+
return json.dumps({"error": str(e)})
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
# ============================================================
|
|
185
|
+
# Finance Tools
|
|
186
|
+
# ============================================================
|
|
187
|
+
|
|
188
|
+
class PortfolioOptimizationTool(BaseTool):
|
|
189
|
+
"""Tool for QAOA-based portfolio optimization."""
|
|
190
|
+
|
|
191
|
+
name: str = "portfolio_optimization"
|
|
192
|
+
description: str = """
|
|
193
|
+
Optimize portfolio allocation using quantum QAOA algorithm.
|
|
194
|
+
Input: JSON with 'assets' (list), 'expected_returns' (list), and optional 'initial_capital', 'steps'.
|
|
195
|
+
Returns: Optimal weights and risk metrics.
|
|
196
|
+
"""
|
|
197
|
+
|
|
198
|
+
def _run(self, input_data: str) -> str:
|
|
199
|
+
"""Execute portfolio optimization."""
|
|
200
|
+
import json
|
|
201
|
+
|
|
202
|
+
try:
|
|
203
|
+
data = json.loads(input_data) if isinstance(input_data, str) else input_data
|
|
204
|
+
assets = data.get("assets", ["AAPL", "GOOGL", "MSFT"])
|
|
205
|
+
returns = data.get("expected_returns", [0.12, 0.10, 0.11])
|
|
206
|
+
capital = data.get("initial_capital", 100000)
|
|
207
|
+
steps = data.get("steps", 50)
|
|
208
|
+
|
|
209
|
+
from quantumflow.pipeline.finance.portfolio_optimization import (
|
|
210
|
+
PortfolioOptimizationPipeline,
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
pipeline = PortfolioOptimizationPipeline(
|
|
214
|
+
name="Agent Portfolio Optimization",
|
|
215
|
+
assets=assets,
|
|
216
|
+
expected_returns=returns,
|
|
217
|
+
initial_capital=capital,
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
result = pipeline.run(total_steps=steps)
|
|
221
|
+
|
|
222
|
+
return json.dumps({
|
|
223
|
+
"status": result.status,
|
|
224
|
+
"optimal_weights": dict(zip(assets, result.final_state.weights)),
|
|
225
|
+
"final_value": result.final_state.portfolio_value,
|
|
226
|
+
"sharpe_ratio": result.final_state.metrics.get("sharpe_ratio"),
|
|
227
|
+
"var": result.final_state.metrics.get("var"),
|
|
228
|
+
"max_drawdown": result.final_state.metrics.get("max_drawdown"),
|
|
229
|
+
"market_regime": result.final_state.market_regime,
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
except Exception as e:
|
|
233
|
+
return json.dumps({"error": str(e)})
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
class RiskAnalysisTool(BaseTool):
|
|
237
|
+
"""Tool for portfolio risk analysis."""
|
|
238
|
+
|
|
239
|
+
name: str = "risk_analysis"
|
|
240
|
+
description: str = """
|
|
241
|
+
Analyze risk metrics for a given portfolio.
|
|
242
|
+
Input: JSON with 'weights' (dict of asset:weight), 'returns_history' (list of daily returns).
|
|
243
|
+
Returns: VaR, CVaR, Sharpe ratio, Sortino ratio, and risk classification.
|
|
244
|
+
"""
|
|
245
|
+
|
|
246
|
+
def _run(self, input_data: str) -> str:
|
|
247
|
+
"""Execute risk analysis."""
|
|
248
|
+
import json
|
|
249
|
+
import math
|
|
250
|
+
|
|
251
|
+
try:
|
|
252
|
+
data = json.loads(input_data) if isinstance(input_data, str) else input_data
|
|
253
|
+
weights = data.get("weights", {"AAPL": 0.5, "GOOGL": 0.5})
|
|
254
|
+
returns_history = data.get("returns_history", [0.01, -0.02, 0.015, -0.01, 0.02])
|
|
255
|
+
|
|
256
|
+
if not returns_history:
|
|
257
|
+
return json.dumps({"error": "No returns history provided"})
|
|
258
|
+
|
|
259
|
+
# Calculate metrics
|
|
260
|
+
mean_return = sum(returns_history) / len(returns_history)
|
|
261
|
+
variance = sum((r - mean_return) ** 2 for r in returns_history) / len(returns_history)
|
|
262
|
+
std = math.sqrt(variance) if variance > 0 else 0.0001
|
|
263
|
+
|
|
264
|
+
# VaR (95%)
|
|
265
|
+
sorted_returns = sorted(returns_history)
|
|
266
|
+
var_idx = int(0.05 * len(sorted_returns))
|
|
267
|
+
var_95 = -sorted_returns[var_idx] if var_idx < len(sorted_returns) else 0
|
|
268
|
+
|
|
269
|
+
# CVaR
|
|
270
|
+
cvar = -sum(sorted_returns[:max(1, var_idx)]) / max(1, var_idx)
|
|
271
|
+
|
|
272
|
+
# Sharpe (assuming 2% risk-free rate)
|
|
273
|
+
rf_daily = 0.02 / 252
|
|
274
|
+
sharpe = (mean_return - rf_daily) / std if std > 0 else 0
|
|
275
|
+
|
|
276
|
+
# Risk classification
|
|
277
|
+
if var_95 > 0.05:
|
|
278
|
+
risk_class = "high"
|
|
279
|
+
elif var_95 > 0.02:
|
|
280
|
+
risk_class = "medium"
|
|
281
|
+
else:
|
|
282
|
+
risk_class = "low"
|
|
283
|
+
|
|
284
|
+
return json.dumps({
|
|
285
|
+
"mean_daily_return": round(mean_return, 6),
|
|
286
|
+
"volatility": round(std, 6),
|
|
287
|
+
"var_95": round(var_95, 6),
|
|
288
|
+
"cvar_95": round(cvar, 6),
|
|
289
|
+
"sharpe_ratio": round(sharpe, 4),
|
|
290
|
+
"risk_classification": risk_class,
|
|
291
|
+
"portfolio_weights": weights,
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
except Exception as e:
|
|
295
|
+
return json.dumps({"error": str(e)})
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
class RegimeDetectionTool(BaseTool):
|
|
299
|
+
"""Tool for market regime detection."""
|
|
300
|
+
|
|
301
|
+
name: str = "regime_detection"
|
|
302
|
+
description: str = """
|
|
303
|
+
Detect current market regime from price/return data.
|
|
304
|
+
Input: JSON with 'returns_history' (list of recent daily returns).
|
|
305
|
+
Returns: Detected regime (bull/bear/sideways/crisis) and confidence.
|
|
306
|
+
"""
|
|
307
|
+
|
|
308
|
+
def _run(self, input_data: str) -> str:
|
|
309
|
+
"""Execute regime detection."""
|
|
310
|
+
import json
|
|
311
|
+
import math
|
|
312
|
+
|
|
313
|
+
try:
|
|
314
|
+
data = json.loads(input_data) if isinstance(input_data, str) else input_data
|
|
315
|
+
returns = data.get("returns_history", [])
|
|
316
|
+
|
|
317
|
+
if len(returns) < 5:
|
|
318
|
+
return json.dumps({"error": "Need at least 5 returns for regime detection"})
|
|
319
|
+
|
|
320
|
+
# Calculate statistics
|
|
321
|
+
mean_return = sum(returns) / len(returns)
|
|
322
|
+
variance = sum((r - mean_return) ** 2 for r in returns) / len(returns)
|
|
323
|
+
volatility = math.sqrt(variance)
|
|
324
|
+
|
|
325
|
+
# Regime classification
|
|
326
|
+
if mean_return > 0.001 and volatility < 0.02:
|
|
327
|
+
regime = "bull"
|
|
328
|
+
confidence = min(0.9, 0.5 + mean_return * 10)
|
|
329
|
+
elif mean_return < -0.001 and volatility < 0.02:
|
|
330
|
+
regime = "bear"
|
|
331
|
+
confidence = min(0.9, 0.5 + abs(mean_return) * 10)
|
|
332
|
+
elif volatility > 0.03:
|
|
333
|
+
regime = "crisis"
|
|
334
|
+
confidence = min(0.95, 0.5 + volatility * 10)
|
|
335
|
+
else:
|
|
336
|
+
regime = "sideways"
|
|
337
|
+
confidence = 0.6
|
|
338
|
+
|
|
339
|
+
return json.dumps({
|
|
340
|
+
"regime": regime,
|
|
341
|
+
"confidence": round(confidence, 3),
|
|
342
|
+
"mean_return": round(mean_return, 6),
|
|
343
|
+
"volatility": round(volatility, 6),
|
|
344
|
+
"recommendation": {
|
|
345
|
+
"bull": "Consider increasing equity exposure",
|
|
346
|
+
"bear": "Consider defensive positions or hedging",
|
|
347
|
+
"sideways": "Maintain current allocation",
|
|
348
|
+
"crisis": "Reduce risk exposure, increase cash",
|
|
349
|
+
}[regime],
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
except Exception as e:
|
|
353
|
+
return json.dumps({"error": str(e)})
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
# ============================================================
|
|
357
|
+
# Agent Classes
|
|
358
|
+
# ============================================================
|
|
359
|
+
|
|
360
|
+
@dataclass
|
|
361
|
+
class AgentConfig:
|
|
362
|
+
"""Configuration for domain agents."""
|
|
363
|
+
|
|
364
|
+
verbose: bool = True
|
|
365
|
+
allow_delegation: bool = False
|
|
366
|
+
max_iterations: int = 10
|
|
367
|
+
backend: str = "simulator"
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
class QuantumHealthcareAgent:
|
|
371
|
+
"""
|
|
372
|
+
Quantum-powered healthcare agent for CrewAI.
|
|
373
|
+
|
|
374
|
+
Specializes in:
|
|
375
|
+
- Protein folding simulations
|
|
376
|
+
- Mutation effect analysis
|
|
377
|
+
- Drug binding predictions
|
|
378
|
+
"""
|
|
379
|
+
|
|
380
|
+
ROLE = "Quantum Healthcare Researcher"
|
|
381
|
+
GOAL = "Analyze proteins and molecular structures using quantum computing"
|
|
382
|
+
BACKSTORY = """You are a quantum computing specialist focused on healthcare
|
|
383
|
+
and drug discovery applications. You use VQE-based protein folding simulations
|
|
384
|
+
to analyze molecular structures and predict drug interactions."""
|
|
385
|
+
|
|
386
|
+
@classmethod
|
|
387
|
+
def get_tools(cls) -> List[Any]:
|
|
388
|
+
"""Get healthcare-specific tools."""
|
|
389
|
+
if not CREWAI_AVAILABLE:
|
|
390
|
+
return []
|
|
391
|
+
|
|
392
|
+
return [
|
|
393
|
+
ProteinFoldingTool(),
|
|
394
|
+
MutationBenchmarkTool(),
|
|
395
|
+
DrugBindingTool(),
|
|
396
|
+
]
|
|
397
|
+
|
|
398
|
+
@classmethod
|
|
399
|
+
def create(
|
|
400
|
+
cls,
|
|
401
|
+
llm: Any,
|
|
402
|
+
config: Optional[AgentConfig] = None,
|
|
403
|
+
) -> Optional["Agent"]:
|
|
404
|
+
"""
|
|
405
|
+
Create a healthcare agent.
|
|
406
|
+
|
|
407
|
+
Args:
|
|
408
|
+
llm: Language model for the agent
|
|
409
|
+
config: Agent configuration
|
|
410
|
+
|
|
411
|
+
Returns:
|
|
412
|
+
CrewAI Agent or None if unavailable
|
|
413
|
+
"""
|
|
414
|
+
if not CREWAI_AVAILABLE:
|
|
415
|
+
logger.warning("CrewAI not available, cannot create agent")
|
|
416
|
+
return None
|
|
417
|
+
|
|
418
|
+
config = config or AgentConfig()
|
|
419
|
+
|
|
420
|
+
return Agent(
|
|
421
|
+
role=cls.ROLE,
|
|
422
|
+
goal=cls.GOAL,
|
|
423
|
+
backstory=cls.BACKSTORY,
|
|
424
|
+
llm=llm,
|
|
425
|
+
tools=cls.get_tools(),
|
|
426
|
+
verbose=config.verbose,
|
|
427
|
+
allow_delegation=config.allow_delegation,
|
|
428
|
+
max_iter=config.max_iterations,
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
class QuantumFinanceAgent:
|
|
433
|
+
"""
|
|
434
|
+
Quantum-powered finance agent for CrewAI.
|
|
435
|
+
|
|
436
|
+
Specializes in:
|
|
437
|
+
- Portfolio optimization (QAOA)
|
|
438
|
+
- Risk analysis (VaR, CVaR)
|
|
439
|
+
- Market regime detection
|
|
440
|
+
"""
|
|
441
|
+
|
|
442
|
+
ROLE = "Quantum Finance Analyst"
|
|
443
|
+
GOAL = "Optimize portfolios and analyze financial risk using quantum computing"
|
|
444
|
+
BACKSTORY = """You are a quantitative finance expert who leverages quantum
|
|
445
|
+
algorithms for portfolio optimization and risk management. You use QAOA
|
|
446
|
+
for portfolio construction and quantum-enhanced risk metrics."""
|
|
447
|
+
|
|
448
|
+
@classmethod
|
|
449
|
+
def get_tools(cls) -> List[Any]:
|
|
450
|
+
"""Get finance-specific tools."""
|
|
451
|
+
if not CREWAI_AVAILABLE:
|
|
452
|
+
return []
|
|
453
|
+
|
|
454
|
+
return [
|
|
455
|
+
PortfolioOptimizationTool(),
|
|
456
|
+
RiskAnalysisTool(),
|
|
457
|
+
RegimeDetectionTool(),
|
|
458
|
+
]
|
|
459
|
+
|
|
460
|
+
@classmethod
|
|
461
|
+
def create(
|
|
462
|
+
cls,
|
|
463
|
+
llm: Any,
|
|
464
|
+
config: Optional[AgentConfig] = None,
|
|
465
|
+
) -> Optional["Agent"]:
|
|
466
|
+
"""
|
|
467
|
+
Create a finance agent.
|
|
468
|
+
|
|
469
|
+
Args:
|
|
470
|
+
llm: Language model for the agent
|
|
471
|
+
config: Agent configuration
|
|
472
|
+
|
|
473
|
+
Returns:
|
|
474
|
+
CrewAI Agent or None if unavailable
|
|
475
|
+
"""
|
|
476
|
+
if not CREWAI_AVAILABLE:
|
|
477
|
+
logger.warning("CrewAI not available, cannot create agent")
|
|
478
|
+
return None
|
|
479
|
+
|
|
480
|
+
config = config or AgentConfig()
|
|
481
|
+
|
|
482
|
+
return Agent(
|
|
483
|
+
role=cls.ROLE,
|
|
484
|
+
goal=cls.GOAL,
|
|
485
|
+
backstory=cls.BACKSTORY,
|
|
486
|
+
llm=llm,
|
|
487
|
+
tools=cls.get_tools(),
|
|
488
|
+
verbose=config.verbose,
|
|
489
|
+
allow_delegation=config.allow_delegation,
|
|
490
|
+
max_iter=config.max_iterations,
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
# ============================================================
|
|
495
|
+
# Crew Factory
|
|
496
|
+
# ============================================================
|
|
497
|
+
|
|
498
|
+
def create_healthcare_crew(
|
|
499
|
+
llm: Any,
|
|
500
|
+
tasks: List[Dict[str, str]],
|
|
501
|
+
verbose: bool = True,
|
|
502
|
+
) -> Optional["Crew"]:
|
|
503
|
+
"""
|
|
504
|
+
Create a healthcare-focused crew.
|
|
505
|
+
|
|
506
|
+
Args:
|
|
507
|
+
llm: Language model for agents
|
|
508
|
+
tasks: List of task definitions with 'description' and 'expected_output'
|
|
509
|
+
verbose: Enable verbose output
|
|
510
|
+
|
|
511
|
+
Returns:
|
|
512
|
+
CrewAI Crew or None if unavailable
|
|
513
|
+
"""
|
|
514
|
+
if not CREWAI_AVAILABLE:
|
|
515
|
+
return None
|
|
516
|
+
|
|
517
|
+
agent = QuantumHealthcareAgent.create(llm)
|
|
518
|
+
if not agent:
|
|
519
|
+
return None
|
|
520
|
+
|
|
521
|
+
crew_tasks = [
|
|
522
|
+
Task(
|
|
523
|
+
description=t["description"],
|
|
524
|
+
expected_output=t.get("expected_output", "Analysis results"),
|
|
525
|
+
agent=agent,
|
|
526
|
+
)
|
|
527
|
+
for t in tasks
|
|
528
|
+
]
|
|
529
|
+
|
|
530
|
+
return Crew(
|
|
531
|
+
agents=[agent],
|
|
532
|
+
tasks=crew_tasks,
|
|
533
|
+
verbose=verbose,
|
|
534
|
+
)
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
def create_finance_crew(
|
|
538
|
+
llm: Any,
|
|
539
|
+
tasks: List[Dict[str, str]],
|
|
540
|
+
verbose: bool = True,
|
|
541
|
+
) -> Optional["Crew"]:
|
|
542
|
+
"""
|
|
543
|
+
Create a finance-focused crew.
|
|
544
|
+
|
|
545
|
+
Args:
|
|
546
|
+
llm: Language model for agents
|
|
547
|
+
tasks: List of task definitions with 'description' and 'expected_output'
|
|
548
|
+
verbose: Enable verbose output
|
|
549
|
+
|
|
550
|
+
Returns:
|
|
551
|
+
CrewAI Crew or None if unavailable
|
|
552
|
+
"""
|
|
553
|
+
if not CREWAI_AVAILABLE:
|
|
554
|
+
return None
|
|
555
|
+
|
|
556
|
+
agent = QuantumFinanceAgent.create(llm)
|
|
557
|
+
if not agent:
|
|
558
|
+
return None
|
|
559
|
+
|
|
560
|
+
crew_tasks = [
|
|
561
|
+
Task(
|
|
562
|
+
description=t["description"],
|
|
563
|
+
expected_output=t.get("expected_output", "Analysis results"),
|
|
564
|
+
agent=agent,
|
|
565
|
+
)
|
|
566
|
+
for t in tasks
|
|
567
|
+
]
|
|
568
|
+
|
|
569
|
+
return Crew(
|
|
570
|
+
agents=[agent],
|
|
571
|
+
tasks=crew_tasks,
|
|
572
|
+
verbose=verbose,
|
|
573
|
+
)
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
def create_quantum_research_crew(
|
|
577
|
+
llm: Any,
|
|
578
|
+
tasks: List[Dict[str, str]],
|
|
579
|
+
verbose: bool = True,
|
|
580
|
+
) -> Optional["Crew"]:
|
|
581
|
+
"""
|
|
582
|
+
Create a multi-domain quantum research crew with both healthcare and finance agents.
|
|
583
|
+
|
|
584
|
+
Args:
|
|
585
|
+
llm: Language model for agents
|
|
586
|
+
tasks: List of task definitions
|
|
587
|
+
verbose: Enable verbose output
|
|
588
|
+
|
|
589
|
+
Returns:
|
|
590
|
+
CrewAI Crew or None if unavailable
|
|
591
|
+
"""
|
|
592
|
+
if not CREWAI_AVAILABLE:
|
|
593
|
+
return None
|
|
594
|
+
|
|
595
|
+
health_agent = QuantumHealthcareAgent.create(llm)
|
|
596
|
+
finance_agent = QuantumFinanceAgent.create(llm)
|
|
597
|
+
|
|
598
|
+
if not health_agent or not finance_agent:
|
|
599
|
+
return None
|
|
600
|
+
|
|
601
|
+
agents = [health_agent, finance_agent]
|
|
602
|
+
|
|
603
|
+
crew_tasks = [
|
|
604
|
+
Task(
|
|
605
|
+
description=t["description"],
|
|
606
|
+
expected_output=t.get("expected_output", "Analysis results"),
|
|
607
|
+
agent=health_agent if "protein" in t["description"].lower() or "drug" in t["description"].lower()
|
|
608
|
+
else finance_agent,
|
|
609
|
+
)
|
|
610
|
+
for t in tasks
|
|
611
|
+
]
|
|
612
|
+
|
|
613
|
+
return Crew(
|
|
614
|
+
agents=agents,
|
|
615
|
+
tasks=crew_tasks,
|
|
616
|
+
verbose=verbose,
|
|
617
|
+
)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
QuantumFlow Data Pipeline System.
|
|
3
|
+
|
|
4
|
+
Provides intelligent data pipelines with:
|
|
5
|
+
- Checkpointing for long-running operations
|
|
6
|
+
- Anomaly detection (gradient explosion, NaN, domain-specific)
|
|
7
|
+
- LSTM-like temporal memory for pattern matching
|
|
8
|
+
- Auto-rollback on critical failures
|
|
9
|
+
|
|
10
|
+
Domain-specific pipelines:
|
|
11
|
+
- Healthcare: Protein folding with VQE
|
|
12
|
+
- Finance: Portfolio optimization with QAOA
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from quantumflow.pipeline.base_pipeline import BasePipeline, PipelineConfig, PipelineState
|
|
16
|
+
from quantumflow.pipeline.checkpoint_manager import CheckpointManager
|
|
17
|
+
from quantumflow.pipeline.anomaly_detector import AnomalyDetector, AnomalyResult
|
|
18
|
+
from quantumflow.pipeline.temporal_memory import TemporalMemoryStore, LSTMMemory
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"BasePipeline",
|
|
22
|
+
"PipelineConfig",
|
|
23
|
+
"PipelineState",
|
|
24
|
+
"CheckpointManager",
|
|
25
|
+
"AnomalyDetector",
|
|
26
|
+
"AnomalyResult",
|
|
27
|
+
"TemporalMemoryStore",
|
|
28
|
+
"LSTMMemory",
|
|
29
|
+
]
|