euriai 1.0.15__py3-none-any.whl → 1.0.17__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.
- euriai/__init__.py +203 -203
- euriai/langgraph.py +147 -1
- {euriai-1.0.15.dist-info → euriai-1.0.17.dist-info}/METADATA +1 -1
- {euriai-1.0.15.dist-info → euriai-1.0.17.dist-info}/RECORD +7 -7
- {euriai-1.0.15.dist-info → euriai-1.0.17.dist-info}/WHEEL +0 -0
- {euriai-1.0.15.dist-info → euriai-1.0.17.dist-info}/entry_points.txt +0 -0
- {euriai-1.0.15.dist-info → euriai-1.0.17.dist-info}/top_level.txt +0 -0
euriai/__init__.py
CHANGED
@@ -1,204 +1,204 @@
|
|
1
|
-
"""
|
2
|
-
Euri AI Python SDK
|
3
|
-
|
4
|
-
A comprehensive Python SDK for the Euri AI API with integrations for popular frameworks.
|
5
|
-
"""
|
6
|
-
|
7
|
-
__version__ = "1.0.
|
8
|
-
|
9
|
-
# Core imports that should always work
|
10
|
-
try:
|
11
|
-
from .client import EuriaiClient
|
12
|
-
except ImportError as e:
|
13
|
-
print(f"Warning: Could not import EuriaiClient: {e}")
|
14
|
-
EuriaiClient = None
|
15
|
-
|
16
|
-
try:
|
17
|
-
from .embedding import EuriaiEmbeddingClient
|
18
|
-
# Backward compatibility alias
|
19
|
-
EuriaiEmbedding = EuriaiEmbeddingClient
|
20
|
-
except ImportError as e:
|
21
|
-
print(f"Warning: Could not import EuriaiEmbeddingClient: {e}")
|
22
|
-
EuriaiEmbeddingClient = None
|
23
|
-
EuriaiEmbedding = None
|
24
|
-
|
25
|
-
# Main exports (only include what was successfully imported)
|
26
|
-
__all__ = []
|
27
|
-
if EuriaiClient is not None:
|
28
|
-
__all__.append("EuriaiClient")
|
29
|
-
if EuriaiEmbeddingClient is not None:
|
30
|
-
__all__.extend(["EuriaiEmbeddingClient", "EuriaiEmbedding"])
|
31
|
-
|
32
|
-
|
33
|
-
# Helper functions for optional dependencies
|
34
|
-
def check_optional_dependency(package_name: str, integration_name: str, install_extra: str = None) -> bool:
|
35
|
-
"""
|
36
|
-
Check if an optional dependency is installed and provide helpful installation instructions.
|
37
|
-
|
38
|
-
Args:
|
39
|
-
package_name: The actual package name to import
|
40
|
-
integration_name: The friendly name for the integration
|
41
|
-
install_extra: The extras_require key for pip install euriai[extra]
|
42
|
-
|
43
|
-
Returns:
|
44
|
-
bool: True if package is available, False otherwise
|
45
|
-
|
46
|
-
Raises:
|
47
|
-
ImportError: With helpful installation instructions
|
48
|
-
"""
|
49
|
-
try:
|
50
|
-
__import__(package_name)
|
51
|
-
return True
|
52
|
-
except ImportError:
|
53
|
-
extra_option = f"euriai[{install_extra}]" if install_extra else f"euriai[{integration_name.lower()}]"
|
54
|
-
|
55
|
-
error_msg = (
|
56
|
-
f"{integration_name} is not installed. Please install it using one of these methods:\n\n"
|
57
|
-
f"Option 1 (Recommended): Install with euriai extras:\n"
|
58
|
-
f" pip install {extra_option}\n\n"
|
59
|
-
f"Option 2: Install {integration_name} directly:\n"
|
60
|
-
f" pip install {package_name}\n\n"
|
61
|
-
f"Option 3: Install all euriai integrations:\n"
|
62
|
-
f" pip install euriai[all]\n"
|
63
|
-
)
|
64
|
-
|
65
|
-
raise ImportError(error_msg)
|
66
|
-
|
67
|
-
|
68
|
-
def install_optional_dependency(package_name: str, integration_name: str, install_extra: str = None) -> bool:
|
69
|
-
"""
|
70
|
-
Attempt to automatically install an optional dependency (USE WITH CAUTION).
|
71
|
-
|
72
|
-
This function is provided for convenience but automatic installation can be risky.
|
73
|
-
It's generally better to install dependencies manually.
|
74
|
-
|
75
|
-
Args:
|
76
|
-
package_name: The actual package name to install
|
77
|
-
integration_name: The friendly name for the integration
|
78
|
-
install_extra: The extras_require key for pip install euriai[extra]
|
79
|
-
|
80
|
-
Returns:
|
81
|
-
bool: True if installation succeeded, False otherwise
|
82
|
-
"""
|
83
|
-
import subprocess
|
84
|
-
import sys
|
85
|
-
|
86
|
-
try:
|
87
|
-
# Try to import first
|
88
|
-
__import__(package_name)
|
89
|
-
print(f"✓ {integration_name} is already installed")
|
90
|
-
return True
|
91
|
-
except ImportError:
|
92
|
-
pass
|
93
|
-
|
94
|
-
# Ask user for confirmation
|
95
|
-
extra_option = f"euriai[{install_extra}]" if install_extra else f"euriai[{integration_name.lower()}]"
|
96
|
-
|
97
|
-
print(f"🔍 {integration_name} is not installed.")
|
98
|
-
print(f"📦 Recommended installation: pip install {extra_option}")
|
99
|
-
|
100
|
-
response = input(f"Would you like to automatically install {package_name}? (y/N): ").lower()
|
101
|
-
|
102
|
-
if response in ['y', 'yes']:
|
103
|
-
try:
|
104
|
-
print(f"📥 Installing {package_name}...")
|
105
|
-
subprocess.check_call([sys.executable, "-m", "pip", "install", package_name])
|
106
|
-
print(f"✅ {integration_name} installed successfully!")
|
107
|
-
return True
|
108
|
-
except subprocess.CalledProcessError as e:
|
109
|
-
print(f"❌ Failed to install {package_name}: {e}")
|
110
|
-
print(f"💡 Try manually: pip install {extra_option}")
|
111
|
-
return False
|
112
|
-
else:
|
113
|
-
print(f"💡 To install manually run: pip install {extra_option}")
|
114
|
-
return False
|
115
|
-
|
116
|
-
|
117
|
-
# Lazy loading functions for optional integrations
|
118
|
-
def _get_langchain():
|
119
|
-
"""Lazy import for LangChain integration."""
|
120
|
-
try:
|
121
|
-
from . import langchain
|
122
|
-
return langchain
|
123
|
-
except ImportError:
|
124
|
-
check_optional_dependency("langchain-core", "LangChain", "langchain")
|
125
|
-
|
126
|
-
def _get_crewai():
|
127
|
-
"""Lazy import for CrewAI integration."""
|
128
|
-
try:
|
129
|
-
from . import crewai
|
130
|
-
return crewai
|
131
|
-
except ImportError:
|
132
|
-
check_optional_dependency("crewai", "CrewAI", "crewai")
|
133
|
-
|
134
|
-
def _get_autogen():
|
135
|
-
"""Lazy import for AutoGen integration."""
|
136
|
-
try:
|
137
|
-
from . import autogen
|
138
|
-
return autogen
|
139
|
-
except ImportError:
|
140
|
-
check_optional_dependency("pyautogen", "AutoGen", "autogen")
|
141
|
-
|
142
|
-
def _get_smolagents():
|
143
|
-
"""Lazy import for SmolAgents integration."""
|
144
|
-
try:
|
145
|
-
from . import smolagents
|
146
|
-
return smolagents
|
147
|
-
except ImportError:
|
148
|
-
check_optional_dependency("smolagents", "SmolAgents", "smolagents")
|
149
|
-
|
150
|
-
def _get_langgraph():
|
151
|
-
"""Lazy import for LangGraph integration."""
|
152
|
-
try:
|
153
|
-
from . import langgraph
|
154
|
-
return langgraph
|
155
|
-
except ImportError:
|
156
|
-
check_optional_dependency("langgraph", "LangGraph", "langgraph")
|
157
|
-
|
158
|
-
def _get_llamaindex():
|
159
|
-
"""Lazy import for LlamaIndex integration."""
|
160
|
-
try:
|
161
|
-
from . import llamaindex
|
162
|
-
return llamaindex
|
163
|
-
except ImportError:
|
164
|
-
check_optional_dependency("llama-index", "LlamaIndex", "llama-index")
|
165
|
-
|
166
|
-
|
167
|
-
# Create lazy loading properties
|
168
|
-
class _LazyLoader:
|
169
|
-
"""Lazy loader for optional integrations."""
|
170
|
-
|
171
|
-
@property
|
172
|
-
def langchain(self):
|
173
|
-
return _get_langchain()
|
174
|
-
|
175
|
-
@property
|
176
|
-
def crewai(self):
|
177
|
-
return _get_crewai()
|
178
|
-
|
179
|
-
@property
|
180
|
-
def autogen(self):
|
181
|
-
return _get_autogen()
|
182
|
-
|
183
|
-
@property
|
184
|
-
def smolagents(self):
|
185
|
-
return _get_smolagents()
|
186
|
-
|
187
|
-
@property
|
188
|
-
def langgraph(self):
|
189
|
-
return _get_langgraph()
|
190
|
-
|
191
|
-
@property
|
192
|
-
def llamaindex(self):
|
193
|
-
return _get_llamaindex()
|
194
|
-
|
195
|
-
|
196
|
-
# Create the lazy loader instance
|
197
|
-
_lazy = _LazyLoader()
|
198
|
-
|
199
|
-
# Make the integrations available as module-level attributes
|
200
|
-
def __getattr__(name: str):
|
201
|
-
"""Handle lazy loading of optional integrations."""
|
202
|
-
if hasattr(_lazy, name):
|
203
|
-
return getattr(_lazy, name)
|
1
|
+
"""
|
2
|
+
Euri AI Python SDK
|
3
|
+
|
4
|
+
A comprehensive Python SDK for the Euri AI API with integrations for popular frameworks.
|
5
|
+
"""
|
6
|
+
|
7
|
+
__version__ = "1.0.17"
|
8
|
+
|
9
|
+
# Core imports that should always work
|
10
|
+
try:
|
11
|
+
from .client import EuriaiClient
|
12
|
+
except ImportError as e:
|
13
|
+
print(f"Warning: Could not import EuriaiClient: {e}")
|
14
|
+
EuriaiClient = None
|
15
|
+
|
16
|
+
try:
|
17
|
+
from .embedding import EuriaiEmbeddingClient
|
18
|
+
# Backward compatibility alias
|
19
|
+
EuriaiEmbedding = EuriaiEmbeddingClient
|
20
|
+
except ImportError as e:
|
21
|
+
print(f"Warning: Could not import EuriaiEmbeddingClient: {e}")
|
22
|
+
EuriaiEmbeddingClient = None
|
23
|
+
EuriaiEmbedding = None
|
24
|
+
|
25
|
+
# Main exports (only include what was successfully imported)
|
26
|
+
__all__ = []
|
27
|
+
if EuriaiClient is not None:
|
28
|
+
__all__.append("EuriaiClient")
|
29
|
+
if EuriaiEmbeddingClient is not None:
|
30
|
+
__all__.extend(["EuriaiEmbeddingClient", "EuriaiEmbedding"])
|
31
|
+
|
32
|
+
|
33
|
+
# Helper functions for optional dependencies
|
34
|
+
def check_optional_dependency(package_name: str, integration_name: str, install_extra: str = None) -> bool:
|
35
|
+
"""
|
36
|
+
Check if an optional dependency is installed and provide helpful installation instructions.
|
37
|
+
|
38
|
+
Args:
|
39
|
+
package_name: The actual package name to import
|
40
|
+
integration_name: The friendly name for the integration
|
41
|
+
install_extra: The extras_require key for pip install euriai[extra]
|
42
|
+
|
43
|
+
Returns:
|
44
|
+
bool: True if package is available, False otherwise
|
45
|
+
|
46
|
+
Raises:
|
47
|
+
ImportError: With helpful installation instructions
|
48
|
+
"""
|
49
|
+
try:
|
50
|
+
__import__(package_name)
|
51
|
+
return True
|
52
|
+
except ImportError:
|
53
|
+
extra_option = f"euriai[{install_extra}]" if install_extra else f"euriai[{integration_name.lower()}]"
|
54
|
+
|
55
|
+
error_msg = (
|
56
|
+
f"{integration_name} is not installed. Please install it using one of these methods:\n\n"
|
57
|
+
f"Option 1 (Recommended): Install with euriai extras:\n"
|
58
|
+
f" pip install {extra_option}\n\n"
|
59
|
+
f"Option 2: Install {integration_name} directly:\n"
|
60
|
+
f" pip install {package_name}\n\n"
|
61
|
+
f"Option 3: Install all euriai integrations:\n"
|
62
|
+
f" pip install euriai[all]\n"
|
63
|
+
)
|
64
|
+
|
65
|
+
raise ImportError(error_msg)
|
66
|
+
|
67
|
+
|
68
|
+
def install_optional_dependency(package_name: str, integration_name: str, install_extra: str = None) -> bool:
|
69
|
+
"""
|
70
|
+
Attempt to automatically install an optional dependency (USE WITH CAUTION).
|
71
|
+
|
72
|
+
This function is provided for convenience but automatic installation can be risky.
|
73
|
+
It's generally better to install dependencies manually.
|
74
|
+
|
75
|
+
Args:
|
76
|
+
package_name: The actual package name to install
|
77
|
+
integration_name: The friendly name for the integration
|
78
|
+
install_extra: The extras_require key for pip install euriai[extra]
|
79
|
+
|
80
|
+
Returns:
|
81
|
+
bool: True if installation succeeded, False otherwise
|
82
|
+
"""
|
83
|
+
import subprocess
|
84
|
+
import sys
|
85
|
+
|
86
|
+
try:
|
87
|
+
# Try to import first
|
88
|
+
__import__(package_name)
|
89
|
+
print(f"✓ {integration_name} is already installed")
|
90
|
+
return True
|
91
|
+
except ImportError:
|
92
|
+
pass
|
93
|
+
|
94
|
+
# Ask user for confirmation
|
95
|
+
extra_option = f"euriai[{install_extra}]" if install_extra else f"euriai[{integration_name.lower()}]"
|
96
|
+
|
97
|
+
print(f"🔍 {integration_name} is not installed.")
|
98
|
+
print(f"📦 Recommended installation: pip install {extra_option}")
|
99
|
+
|
100
|
+
response = input(f"Would you like to automatically install {package_name}? (y/N): ").lower()
|
101
|
+
|
102
|
+
if response in ['y', 'yes']:
|
103
|
+
try:
|
104
|
+
print(f"📥 Installing {package_name}...")
|
105
|
+
subprocess.check_call([sys.executable, "-m", "pip", "install", package_name])
|
106
|
+
print(f"✅ {integration_name} installed successfully!")
|
107
|
+
return True
|
108
|
+
except subprocess.CalledProcessError as e:
|
109
|
+
print(f"❌ Failed to install {package_name}: {e}")
|
110
|
+
print(f"💡 Try manually: pip install {extra_option}")
|
111
|
+
return False
|
112
|
+
else:
|
113
|
+
print(f"💡 To install manually run: pip install {extra_option}")
|
114
|
+
return False
|
115
|
+
|
116
|
+
|
117
|
+
# Lazy loading functions for optional integrations
|
118
|
+
def _get_langchain():
|
119
|
+
"""Lazy import for LangChain integration."""
|
120
|
+
try:
|
121
|
+
from . import langchain
|
122
|
+
return langchain
|
123
|
+
except ImportError:
|
124
|
+
check_optional_dependency("langchain-core", "LangChain", "langchain")
|
125
|
+
|
126
|
+
def _get_crewai():
|
127
|
+
"""Lazy import for CrewAI integration."""
|
128
|
+
try:
|
129
|
+
from . import crewai
|
130
|
+
return crewai
|
131
|
+
except ImportError:
|
132
|
+
check_optional_dependency("crewai", "CrewAI", "crewai")
|
133
|
+
|
134
|
+
def _get_autogen():
|
135
|
+
"""Lazy import for AutoGen integration."""
|
136
|
+
try:
|
137
|
+
from . import autogen
|
138
|
+
return autogen
|
139
|
+
except ImportError:
|
140
|
+
check_optional_dependency("pyautogen", "AutoGen", "autogen")
|
141
|
+
|
142
|
+
def _get_smolagents():
|
143
|
+
"""Lazy import for SmolAgents integration."""
|
144
|
+
try:
|
145
|
+
from . import smolagents
|
146
|
+
return smolagents
|
147
|
+
except ImportError:
|
148
|
+
check_optional_dependency("smolagents", "SmolAgents", "smolagents")
|
149
|
+
|
150
|
+
def _get_langgraph():
|
151
|
+
"""Lazy import for LangGraph integration."""
|
152
|
+
try:
|
153
|
+
from . import langgraph
|
154
|
+
return langgraph
|
155
|
+
except ImportError:
|
156
|
+
check_optional_dependency("langgraph", "LangGraph", "langgraph")
|
157
|
+
|
158
|
+
def _get_llamaindex():
|
159
|
+
"""Lazy import for LlamaIndex integration."""
|
160
|
+
try:
|
161
|
+
from . import llamaindex
|
162
|
+
return llamaindex
|
163
|
+
except ImportError:
|
164
|
+
check_optional_dependency("llama-index", "LlamaIndex", "llama-index")
|
165
|
+
|
166
|
+
|
167
|
+
# Create lazy loading properties
|
168
|
+
class _LazyLoader:
|
169
|
+
"""Lazy loader for optional integrations."""
|
170
|
+
|
171
|
+
@property
|
172
|
+
def langchain(self):
|
173
|
+
return _get_langchain()
|
174
|
+
|
175
|
+
@property
|
176
|
+
def crewai(self):
|
177
|
+
return _get_crewai()
|
178
|
+
|
179
|
+
@property
|
180
|
+
def autogen(self):
|
181
|
+
return _get_autogen()
|
182
|
+
|
183
|
+
@property
|
184
|
+
def smolagents(self):
|
185
|
+
return _get_smolagents()
|
186
|
+
|
187
|
+
@property
|
188
|
+
def langgraph(self):
|
189
|
+
return _get_langgraph()
|
190
|
+
|
191
|
+
@property
|
192
|
+
def llamaindex(self):
|
193
|
+
return _get_llamaindex()
|
194
|
+
|
195
|
+
|
196
|
+
# Create the lazy loader instance
|
197
|
+
_lazy = _LazyLoader()
|
198
|
+
|
199
|
+
# Make the integrations available as module-level attributes
|
200
|
+
def __getattr__(name: str):
|
201
|
+
"""Handle lazy loading of optional integrations."""
|
202
|
+
if hasattr(_lazy, name):
|
203
|
+
return getattr(_lazy, name)
|
204
204
|
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
euriai/langgraph.py
CHANGED
@@ -248,6 +248,7 @@ class EuriaiLangGraph:
|
|
248
248
|
default_temperature: float = 0.7,
|
249
249
|
default_max_tokens: int = 1000,
|
250
250
|
enable_checkpointing: bool = True,
|
251
|
+
enable_usage_tracking: bool = True,
|
251
252
|
verbose: bool = True
|
252
253
|
):
|
253
254
|
"""
|
@@ -260,6 +261,7 @@ class EuriaiLangGraph:
|
|
260
261
|
default_temperature: Default temperature
|
261
262
|
default_max_tokens: Default max tokens
|
262
263
|
enable_checkpointing: Enable workflow checkpointing
|
264
|
+
enable_usage_tracking: Enable usage statistics tracking
|
263
265
|
verbose: Enable verbose logging
|
264
266
|
"""
|
265
267
|
if not LANGGRAPH_AVAILABLE:
|
@@ -273,6 +275,7 @@ class EuriaiLangGraph:
|
|
273
275
|
self.default_model = default_model
|
274
276
|
self.default_temperature = default_temperature
|
275
277
|
self.default_max_tokens = default_max_tokens
|
278
|
+
self.enable_usage_tracking = enable_usage_tracking
|
276
279
|
self.verbose = verbose
|
277
280
|
|
278
281
|
# Initialize graph
|
@@ -297,8 +300,10 @@ class EuriaiLangGraph:
|
|
297
300
|
"total_runs": 0,
|
298
301
|
"total_nodes_executed": 0,
|
299
302
|
"avg_execution_time": 0.0,
|
303
|
+
"total_api_calls": 0,
|
300
304
|
"errors": 0,
|
301
|
-
"successful_runs": 0
|
305
|
+
"successful_runs": 0,
|
306
|
+
"ai_nodes": {} # Node-specific statistics
|
302
307
|
}
|
303
308
|
|
304
309
|
# Thread pool for async operations
|
@@ -344,6 +349,15 @@ class EuriaiLangGraph:
|
|
344
349
|
self.nodes[name] = ai_node
|
345
350
|
self.graph.add_node(name, ai_node)
|
346
351
|
|
352
|
+
# Initialize node-specific statistics
|
353
|
+
if self.enable_usage_tracking:
|
354
|
+
self.usage_stats["ai_nodes"][name] = {
|
355
|
+
"total_calls": 0,
|
356
|
+
"total_tokens": 0,
|
357
|
+
"errors": 0,
|
358
|
+
"avg_response_time": 0.0
|
359
|
+
}
|
360
|
+
|
347
361
|
if self.verbose:
|
348
362
|
print(f"Added AI node: {name} (model: {ai_node.model})")
|
349
363
|
|
@@ -573,6 +587,17 @@ class EuriaiLangGraph:
|
|
573
587
|
if self.compiled_graph is None:
|
574
588
|
self.compile_graph()
|
575
589
|
|
590
|
+
# Prepare config for checkpointer if needed
|
591
|
+
if config is None:
|
592
|
+
config = {}
|
593
|
+
|
594
|
+
# If checkpointer is enabled and no thread_id provided, create one
|
595
|
+
if self.checkpointer is not None and "configurable" not in config:
|
596
|
+
import uuid
|
597
|
+
config["configurable"] = {
|
598
|
+
"thread_id": str(uuid.uuid4())
|
599
|
+
}
|
600
|
+
|
576
601
|
# Execute workflow asynchronously
|
577
602
|
result = await self.compiled_graph.ainvoke(input_state, config=config)
|
578
603
|
|
@@ -613,6 +638,17 @@ class EuriaiLangGraph:
|
|
613
638
|
if self.compiled_graph is None:
|
614
639
|
self.compile_graph()
|
615
640
|
|
641
|
+
# Prepare config for checkpointer if needed
|
642
|
+
if config is None:
|
643
|
+
config = {}
|
644
|
+
|
645
|
+
# If checkpointer is enabled and no thread_id provided, create one
|
646
|
+
if self.checkpointer is not None and "configurable" not in config:
|
647
|
+
import uuid
|
648
|
+
config["configurable"] = {
|
649
|
+
"thread_id": str(uuid.uuid4())
|
650
|
+
}
|
651
|
+
|
616
652
|
for chunk in self.compiled_graph.stream(input_state, config=config):
|
617
653
|
yield chunk
|
618
654
|
|
@@ -634,9 +670,119 @@ class EuriaiLangGraph:
|
|
634
670
|
if self.compiled_graph is None:
|
635
671
|
self.compile_graph()
|
636
672
|
|
673
|
+
# Prepare config for checkpointer if needed
|
674
|
+
if config is None:
|
675
|
+
config = {}
|
676
|
+
|
677
|
+
# If checkpointer is enabled and no thread_id provided, create one
|
678
|
+
if self.checkpointer is not None and "configurable" not in config:
|
679
|
+
import uuid
|
680
|
+
config["configurable"] = {
|
681
|
+
"thread_id": str(uuid.uuid4())
|
682
|
+
}
|
683
|
+
|
637
684
|
async for chunk in self.compiled_graph.astream(input_state, config=config):
|
638
685
|
yield chunk
|
639
686
|
|
687
|
+
async def abatch(
|
688
|
+
self,
|
689
|
+
input_states: List[Dict[str, Any]],
|
690
|
+
config: Optional[Dict[str, Any]] = None
|
691
|
+
) -> List[Dict[str, Any]]:
|
692
|
+
"""
|
693
|
+
Async batch processing of multiple inputs.
|
694
|
+
|
695
|
+
Args:
|
696
|
+
input_states: List of input states to process
|
697
|
+
config: Optional configuration for the run
|
698
|
+
|
699
|
+
Returns:
|
700
|
+
List of final states after workflow execution
|
701
|
+
"""
|
702
|
+
# Prepare config for checkpointer if needed
|
703
|
+
if config is None:
|
704
|
+
config = {}
|
705
|
+
|
706
|
+
# If checkpointer is enabled and no thread_id provided, create one
|
707
|
+
if self.checkpointer is not None and "configurable" not in config:
|
708
|
+
import uuid
|
709
|
+
config["configurable"] = {
|
710
|
+
"thread_id": str(uuid.uuid4())
|
711
|
+
}
|
712
|
+
|
713
|
+
# Process all inputs concurrently
|
714
|
+
results = []
|
715
|
+
for input_state in input_states:
|
716
|
+
result = await self.arun(input_state, config=config)
|
717
|
+
results.append(result)
|
718
|
+
|
719
|
+
return results
|
720
|
+
|
721
|
+
def get_usage_stats(self) -> Dict[str, Any]:
|
722
|
+
"""
|
723
|
+
Get comprehensive usage statistics for the workflow.
|
724
|
+
|
725
|
+
Returns:
|
726
|
+
Dictionary containing usage statistics including:
|
727
|
+
- total_runs: Total number of workflow runs
|
728
|
+
- successful_runs: Number of successful runs
|
729
|
+
- errors: Number of errors
|
730
|
+
- avg_execution_time: Average execution time per run
|
731
|
+
- total_api_calls: Total API calls made
|
732
|
+
- ai_nodes: Node-specific statistics
|
733
|
+
"""
|
734
|
+
if not self.enable_usage_tracking:
|
735
|
+
return {"message": "Usage tracking is disabled"}
|
736
|
+
|
737
|
+
# Update AI node statistics from individual nodes
|
738
|
+
for node_name, ai_node in self.ai_nodes.items():
|
739
|
+
if node_name in self.usage_stats["ai_nodes"]:
|
740
|
+
node_stats = ai_node.usage_stats
|
741
|
+
self.usage_stats["ai_nodes"][node_name].update({
|
742
|
+
"total_calls": node_stats["total_calls"],
|
743
|
+
"total_tokens": node_stats["total_tokens"],
|
744
|
+
"errors": node_stats["errors"],
|
745
|
+
"avg_response_time": node_stats["avg_response_time"]
|
746
|
+
})
|
747
|
+
|
748
|
+
# Add to total API calls
|
749
|
+
self.usage_stats["total_api_calls"] += node_stats["total_calls"]
|
750
|
+
|
751
|
+
return self.usage_stats.copy()
|
752
|
+
|
753
|
+
def reset_usage_stats(self) -> None:
|
754
|
+
"""Reset all usage statistics."""
|
755
|
+
if not self.enable_usage_tracking:
|
756
|
+
return
|
757
|
+
|
758
|
+
self.usage_stats = {
|
759
|
+
"total_runs": 0,
|
760
|
+
"total_nodes_executed": 0,
|
761
|
+
"avg_execution_time": 0.0,
|
762
|
+
"total_api_calls": 0,
|
763
|
+
"errors": 0,
|
764
|
+
"successful_runs": 0,
|
765
|
+
"ai_nodes": {}
|
766
|
+
}
|
767
|
+
|
768
|
+
# Reset individual AI node stats
|
769
|
+
for ai_node in self.ai_nodes.values():
|
770
|
+
ai_node.usage_stats = {
|
771
|
+
"total_calls": 0,
|
772
|
+
"total_tokens": 0,
|
773
|
+
"errors": 0,
|
774
|
+
"avg_response_time": 0.0
|
775
|
+
}
|
776
|
+
|
777
|
+
# Reinitialize AI node stats
|
778
|
+
for name in self.ai_nodes.keys():
|
779
|
+
self.usage_stats["ai_nodes"][name] = {
|
780
|
+
"total_calls": 0,
|
781
|
+
"total_tokens": 0,
|
782
|
+
"errors": 0,
|
783
|
+
"avg_response_time": 0.0
|
784
|
+
}
|
785
|
+
|
640
786
|
def create_workflow_pattern(self, pattern_type: WorkflowType, **kwargs) -> None:
|
641
787
|
"""
|
642
788
|
Create a pre-defined workflow pattern.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
euriai/__init__.py,sha256=
|
1
|
+
euriai/__init__.py,sha256=MQ2FHAw6ruOUDyQAlAqC7cW9Xhg2qhjVb6tX7r54F1w,6427
|
2
2
|
euriai/autogen.py,sha256=z1WHftUgu3_Sn8zDXmf31onikS0p8TwH5JE4llL7ogk,21144
|
3
3
|
euriai/cli.py,sha256=hF1wiiL2QQSfWf8WlLQyNVDBd4YkbiwmMSoPxVbyPTM,3290
|
4
4
|
euriai/client.py,sha256=L-o6hv9N3md-l-hz-kz5nYVaaZqnrREZlo_0jguhF7E,4066
|
@@ -8,12 +8,12 @@ euriai/embedding.py,sha256=uP66Ph1k9Ou6J5RAkztJxlfyj0S0MESOvZ4ulhnVo-o,1270
|
|
8
8
|
euriai/euri_chat.py,sha256=DEAiet1ReRwB4ljkPYaTl1Nb5uc20-JF-3PQjGQZXk4,3567
|
9
9
|
euriai/euri_embed.py,sha256=g7zs1G-ZBDJjOGJtkkfIcV4LPtRcm9wpVWmrfMGn5EM,2919
|
10
10
|
euriai/langchain.py,sha256=gVF9eh21RC1WtDn7SQoEREUDqOObm5IRx6BFZtB5xcc,34968
|
11
|
-
euriai/langgraph.py,sha256=
|
11
|
+
euriai/langgraph.py,sha256=q29D7tg9_7gXr-_uWOMRpOsPh-GRzZOykNGuBFoXgBc,39923
|
12
12
|
euriai/llamaindex.py,sha256=c-ujod2bjL6QIvfAyuIxm1SvSCS00URFElYybKQ5Ew0,26551
|
13
13
|
euriai/n8n.py,sha256=hjkckqyW_hZNL78UkBCof1WvKCKCIjwdvZdAgx6NrB8,3764
|
14
14
|
euriai/smolagents.py,sha256=xlixGx2IWzAPTpSJGsYIK2L-SHGY9Mw1-8GbwVsEYtU,28507
|
15
|
-
euriai-1.0.
|
16
|
-
euriai-1.0.
|
17
|
-
euriai-1.0.
|
18
|
-
euriai-1.0.
|
19
|
-
euriai-1.0.
|
15
|
+
euriai-1.0.17.dist-info/METADATA,sha256=SeWBCt2LKsO9cCeZlX0cBihPuFUGCCCazRnsr2Z2ByA,6807
|
16
|
+
euriai-1.0.17.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
17
|
+
euriai-1.0.17.dist-info/entry_points.txt,sha256=9OkET8KIGcsjQn8UlnpPKRT75s2KW34jq1__1SXtpMA,43
|
18
|
+
euriai-1.0.17.dist-info/top_level.txt,sha256=TG1htJ8cuD62MXn-NJ7DVF21QHY16w6M_QgfF_Er_EQ,7
|
19
|
+
euriai-1.0.17.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|