aiecs 1.7.17__py3-none-any.whl → 1.8.4__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.

Potentially problematic release.


This version of aiecs might be problematic. Click here for more details.

@@ -87,6 +87,7 @@ class XAIClient(BaseLLMClient, OpenAICompatibleFunctionCallingMixin):
87
87
  model: Optional[str] = None,
88
88
  temperature: float = 0.7,
89
89
  max_tokens: Optional[int] = None,
90
+ context: Optional[Dict[str, Any]] = None,
90
91
  functions: Optional[List[Dict[str, Any]]] = None,
91
92
  tools: Optional[List[Dict[str, Any]]] = None,
92
93
  tool_choice: Optional[Any] = None,
@@ -94,8 +95,27 @@ class XAIClient(BaseLLMClient, OpenAICompatibleFunctionCallingMixin):
94
95
  ) -> LLMResponse:
95
96
  """
96
97
  Generate text using xAI API via OpenAI library (supports all Grok models).
97
-
98
+
98
99
  xAI API is OpenAI-compatible, so it supports Function Calling.
100
+
101
+ Args:
102
+ messages: List of conversation messages
103
+ model: Model name (optional, uses default if not provided)
104
+ temperature: Sampling temperature (0.0 to 1.0)
105
+ max_tokens: Maximum tokens to generate
106
+ context: Optional context dictionary containing metadata such as:
107
+ - user_id: User identifier for tracking/billing
108
+ - tenant_id: Tenant identifier for multi-tenant setups
109
+ - request_id: Request identifier for tracing
110
+ - session_id: Session identifier
111
+ - Any other custom metadata for observability or middleware
112
+ functions: List of function schemas (legacy format)
113
+ tools: List of tool schemas (new format, recommended)
114
+ tool_choice: Tool choice strategy
115
+ **kwargs: Additional provider-specific parameters
116
+
117
+ Returns:
118
+ LLMResponse with generated text and metadata
99
119
  """
100
120
  # Check API key availability
101
121
  api_key = self._get_api_key()
@@ -144,6 +164,7 @@ class XAIClient(BaseLLMClient, OpenAICompatibleFunctionCallingMixin):
144
164
  model: Optional[str] = None,
145
165
  temperature: float = 0.7,
146
166
  max_tokens: Optional[int] = None,
167
+ context: Optional[Dict[str, Any]] = None,
147
168
  functions: Optional[List[Dict[str, Any]]] = None,
148
169
  tools: Optional[List[Dict[str, Any]]] = None,
149
170
  tool_choice: Optional[Any] = None,
@@ -152,11 +173,28 @@ class XAIClient(BaseLLMClient, OpenAICompatibleFunctionCallingMixin):
152
173
  ) -> AsyncGenerator[Any, None]:
153
174
  """
154
175
  Stream text using xAI API via OpenAI library (supports all Grok models).
155
-
176
+
156
177
  xAI API is OpenAI-compatible, so it supports Function Calling.
157
-
178
+
158
179
  Args:
180
+ messages: List of conversation messages
181
+ model: Model name (optional, uses default if not provided)
182
+ temperature: Sampling temperature (0.0 to 1.0)
183
+ max_tokens: Maximum tokens to generate
184
+ context: Optional context dictionary containing metadata such as:
185
+ - user_id: User identifier for tracking/billing
186
+ - tenant_id: Tenant identifier for multi-tenant setups
187
+ - request_id: Request identifier for tracing
188
+ - session_id: Session identifier
189
+ - Any other custom metadata for observability or middleware
190
+ functions: List of function schemas (legacy format)
191
+ tools: List of tool schemas (new format, recommended)
192
+ tool_choice: Tool choice strategy
159
193
  return_chunks: If True, returns StreamChunk objects with tool_calls info; if False, returns str tokens only
194
+ **kwargs: Additional provider-specific parameters
195
+
196
+ Yields:
197
+ str or StreamChunk: Text tokens or StreamChunk objects
160
198
  """
161
199
  # Check API key availability
162
200
  api_key = self._get_api_key()
aiecs/llm/protocols.py CHANGED
@@ -4,7 +4,7 @@ LLM Client Protocols
4
4
  Defines Protocol interfaces for LLM clients to enable duck typing and flexible integration.
5
5
  """
6
6
 
7
- from typing import Protocol, List, Optional, AsyncGenerator, runtime_checkable
7
+ from typing import Protocol, List, Optional, AsyncGenerator, runtime_checkable, Dict, Any
8
8
  from aiecs.llm.clients.base_client import LLMMessage, LLMResponse
9
9
 
10
10
 
@@ -31,9 +31,12 @@ class LLMClientProtocol(Protocol):
31
31
  model: Optional[str] = None,
32
32
  temperature: float = 0.7,
33
33
  max_tokens: Optional[int] = None,
34
+ context: Optional[Dict[str, Any]] = None,
34
35
  **kwargs
35
36
  ) -> LLMResponse:
36
37
  # Custom implementation
38
+ # Use context for tracking, billing, observability, etc.
39
+ user_id = context.get("user_id") if context else None
37
40
  pass
38
41
 
39
42
  async def stream_text(
@@ -42,6 +45,7 @@ class LLMClientProtocol(Protocol):
42
45
  model: Optional[str] = None,
43
46
  temperature: float = 0.7,
44
47
  max_tokens: Optional[int] = None,
48
+ context: Optional[Dict[str, Any]] = None,
45
49
  **kwargs
46
50
  ) -> AsyncGenerator[str, None]:
47
51
  # Custom implementation
@@ -67,6 +71,7 @@ class LLMClientProtocol(Protocol):
67
71
  model: Optional[str] = None,
68
72
  temperature: float = 0.7,
69
73
  max_tokens: Optional[int] = None,
74
+ context: Optional[Dict[str, Any]] = None,
70
75
  **kwargs,
71
76
  ) -> LLMResponse:
72
77
  """
@@ -77,6 +82,12 @@ class LLMClientProtocol(Protocol):
77
82
  model: Model name (optional, uses default if not provided)
78
83
  temperature: Sampling temperature (0.0 to 1.0)
79
84
  max_tokens: Maximum tokens to generate
85
+ context: Optional context dictionary containing metadata such as:
86
+ - user_id: User identifier for tracking/billing
87
+ - tenant_id: Tenant identifier for multi-tenant setups
88
+ - request_id: Request identifier for tracing
89
+ - session_id: Session identifier
90
+ - Any other custom metadata for observability or middleware
80
91
  **kwargs: Additional provider-specific parameters
81
92
 
82
93
  Returns:
@@ -90,6 +101,7 @@ class LLMClientProtocol(Protocol):
90
101
  model: Optional[str] = None,
91
102
  temperature: float = 0.7,
92
103
  max_tokens: Optional[int] = None,
104
+ context: Optional[Dict[str, Any]] = None,
93
105
  **kwargs,
94
106
  ) -> AsyncGenerator[str, None]:
95
107
  """
@@ -100,6 +112,12 @@ class LLMClientProtocol(Protocol):
100
112
  model: Model name (optional, uses default if not provided)
101
113
  temperature: Sampling temperature (0.0 to 1.0)
102
114
  max_tokens: Maximum tokens to generate
115
+ context: Optional context dictionary containing metadata such as:
116
+ - user_id: User identifier for tracking/billing
117
+ - tenant_id: Tenant identifier for multi-tenant setups
118
+ - request_id: Request identifier for tracing
119
+ - session_id: Session identifier
120
+ - Any other custom metadata for observability or middleware
103
121
  **kwargs: Additional provider-specific parameters
104
122
 
105
123
  Yields:
@@ -0,0 +1,179 @@
1
+ """
2
+ Image processing utilities for LLM vision support.
3
+
4
+ This module provides functions to handle images in various formats:
5
+ - Image URLs
6
+ - Base64-encoded images
7
+ - Local file paths
8
+ """
9
+
10
+ import os
11
+ import base64
12
+ import mimetypes
13
+ from typing import Union, Optional, Dict, Any
14
+ from urllib.parse import urlparse
15
+ import logging
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ class ImageContent:
21
+ """Represents image content for LLM messages."""
22
+
23
+ def __init__(
24
+ self,
25
+ source: str,
26
+ mime_type: Optional[str] = None,
27
+ detail: Optional[str] = None,
28
+ ):
29
+ """
30
+ Initialize image content.
31
+
32
+ Args:
33
+ source: Image source - can be URL, base64 data URI, or file path
34
+ mime_type: MIME type (e.g., 'image/jpeg', 'image/png'). Auto-detected if not provided.
35
+ detail: Detail level for OpenAI API ('low', 'high', 'auto'). Defaults to 'auto'.
36
+ """
37
+ self.source = source
38
+ self.mime_type = mime_type or self._detect_mime_type(source)
39
+ self.detail = detail or "auto"
40
+
41
+ def _detect_mime_type(self, source: str) -> str:
42
+ """Detect MIME type from source."""
43
+ # Check if it's a data URI
44
+ if source.startswith("data:"):
45
+ header = source.split(",")[0]
46
+ mime_type = header.split(":")[1].split(";")[0]
47
+ return mime_type
48
+
49
+ # Check if it's a URL
50
+ if source.startswith(("http://", "https://")):
51
+ parsed = urlparse(source)
52
+ mime_type, _ = mimetypes.guess_type(parsed.path)
53
+ if mime_type and mime_type.startswith("image/"):
54
+ return mime_type
55
+
56
+ # Check if it's a file path
57
+ if os.path.exists(source):
58
+ mime_type, _ = mimetypes.guess_type(source)
59
+ if mime_type and mime_type.startswith("image/"):
60
+ return mime_type
61
+
62
+ # Default to jpeg if cannot detect
63
+ logger.warning(f"Could not detect MIME type for {source}, defaulting to image/jpeg")
64
+ return "image/jpeg"
65
+
66
+ def is_url(self) -> bool:
67
+ """Check if source is a URL."""
68
+ return self.source.startswith(("http://", "https://"))
69
+
70
+ def is_base64(self) -> bool:
71
+ """Check if source is a base64 data URI."""
72
+ return self.source.startswith("data:")
73
+
74
+ def is_file_path(self) -> bool:
75
+ """Check if source is a local file path."""
76
+ return os.path.exists(self.source) and not self.is_url() and not self.is_base64()
77
+
78
+ def get_base64_data(self) -> str:
79
+ """
80
+ Get base64-encoded image data.
81
+
82
+ Returns:
83
+ Base64 string without data URI prefix
84
+ """
85
+ if self.is_base64():
86
+ # Extract base64 data from data URI
87
+ return self.source.split(",", 1)[1]
88
+ elif self.is_file_path():
89
+ # Read file and encode to base64
90
+ with open(self.source, "rb") as f:
91
+ return base64.b64encode(f.read()).decode("utf-8")
92
+ else:
93
+ raise ValueError(f"Cannot get base64 data from URL: {self.source}. Use URL directly or download first.")
94
+
95
+ def get_url(self) -> str:
96
+ """
97
+ Get image URL.
98
+
99
+ Returns:
100
+ URL string
101
+ """
102
+ if self.is_url():
103
+ return self.source
104
+ else:
105
+ raise ValueError(f"Source is not a URL: {self.source}")
106
+
107
+
108
+ def parse_image_source(source: Union[str, Dict[str, Any]]) -> ImageContent:
109
+ """
110
+ Parse image source into ImageContent object.
111
+
112
+ Args:
113
+ source: Can be:
114
+ - String URL (http://... or https://...)
115
+ - String base64 data URI (data:image/...;base64,...)
116
+ - String file path
117
+ - Dict with 'url', 'data', or 'path' key
118
+
119
+ Returns:
120
+ ImageContent object
121
+ """
122
+ if isinstance(source, dict):
123
+ # Handle dict format
124
+ if "url" in source:
125
+ return ImageContent(
126
+ source=source["url"],
127
+ mime_type=source.get("mime_type"),
128
+ detail=source.get("detail"),
129
+ )
130
+ elif "data" in source:
131
+ # Base64 data
132
+ mime_type = source.get("mime_type", "image/jpeg")
133
+ data = source["data"]
134
+ if not data.startswith("data:"):
135
+ data = f"data:{mime_type};base64,{data}"
136
+ return ImageContent(
137
+ source=data,
138
+ mime_type=mime_type,
139
+ detail=source.get("detail"),
140
+ )
141
+ elif "path" in source:
142
+ return ImageContent(
143
+ source=source["path"],
144
+ mime_type=source.get("mime_type"),
145
+ detail=source.get("detail"),
146
+ )
147
+ else:
148
+ raise ValueError(f"Invalid image dict format: {source}")
149
+ elif isinstance(source, str):
150
+ return ImageContent(source=source)
151
+ else:
152
+ raise TypeError(f"Image source must be str or dict, got {type(source)}")
153
+
154
+
155
+ def validate_image_source(source: str) -> bool:
156
+ """
157
+ Validate that image source is accessible.
158
+
159
+ Args:
160
+ source: Image source (URL, base64, or file path)
161
+
162
+ Returns:
163
+ True if source is valid and accessible
164
+ """
165
+ try:
166
+ img = ImageContent(source)
167
+ if img.is_file_path():
168
+ return os.path.exists(source) and os.path.isfile(source)
169
+ elif img.is_url():
170
+ # URL validation - just check format, not accessibility
171
+ parsed = urlparse(source)
172
+ return bool(parsed.scheme and parsed.netloc)
173
+ elif img.is_base64():
174
+ # Base64 validation - check format
175
+ parts = source.split(",", 1)
176
+ return len(parts) == 2 and parts[0].startswith("data:image/")
177
+ return False
178
+ except Exception:
179
+ return False
aiecs/main.py CHANGED
@@ -142,7 +142,7 @@ async def lifespan(app: FastAPI):
142
142
  app = FastAPI(
143
143
  title="AIECS - AI Execute Services",
144
144
  description="Middleware service for AI-powered task execution and tool orchestration",
145
- version="1.7.17",
145
+ version="1.8.4",
146
146
  lifespan=lifespan,
147
147
  )
148
148
 
@@ -164,7 +164,7 @@ socket_app = socketio.ASGIApp(sio, other_asgi_app=app)
164
164
  @app.get("/health")
165
165
  async def health_check():
166
166
  """Health check endpoint"""
167
- return {"status": "healthy", "service": "aiecs", "version": "1.7.17"}
167
+ return {"status": "healthy", "service": "aiecs", "version": "1.8.4"}
168
168
 
169
169
 
170
170
  # Metrics health check endpoint
@@ -100,7 +100,7 @@ class ScraperTool(BaseTool):
100
100
  # Configuration schema
101
101
  class Config(BaseSettings):
102
102
  """Configuration for the scraper tool
103
-
103
+
104
104
  Automatically reads from environment variables with SCRAPER_TOOL_ prefix.
105
105
  Example: SCRAPER_TOOL_USER_AGENT -> user_agent
106
106
  """
@@ -126,6 +126,10 @@ class ScraperTool(BaseTool):
126
126
  default=False,
127
127
  description="Whether Playwright is available (auto-detected)",
128
128
  )
129
+ use_stealth: bool = Field(
130
+ default=False,
131
+ description="Whether to use stealth mode with Playwright to avoid bot detection",
132
+ )
129
133
 
130
134
  # Schema definitions
131
135
  class Get_httpxSchema(BaseModel):
@@ -508,6 +512,7 @@ class ScraperTool(BaseTool):
508
512
  headers: Optional[Dict[str, str]] = None,
509
513
  output_format: Optional[OutputFormat] = None,
510
514
  output_path: Optional[str] = None,
515
+ use_stealth: Optional[bool] = None,
511
516
  ) -> Dict[str, Any]:
512
517
  """
513
518
  Render a web page using a headless browser (Playwright).
@@ -523,6 +528,7 @@ class ScraperTool(BaseTool):
523
528
  headers (Optional[Dict[str, str]]): Custom headers.
524
529
  output_format (Optional[OutputFormat]): Output format.
525
530
  output_path (Optional[str]): Path to save output.
531
+ use_stealth (Optional[bool]): Whether to use stealth mode. If None, uses config value.
526
532
 
527
533
  Returns:
528
534
  Dict[str, Any]: Rendered page content {'html': str, 'title': str, 'url': str, 'screenshot': Optional[str]}.
@@ -541,6 +547,7 @@ class ScraperTool(BaseTool):
541
547
  scroll_to_bottom,
542
548
  screenshot,
543
549
  screenshot_path,
550
+ use_stealth if use_stealth is not None else self.config.use_stealth,
544
551
  )
545
552
  else:
546
553
  raise RenderingError(f"Unsupported rendering engine: {engine}. Only PLAYWRIGHT is supported.")
@@ -559,8 +566,22 @@ class ScraperTool(BaseTool):
559
566
  scroll_to_bottom: bool,
560
567
  screenshot: bool,
561
568
  screenshot_path: Optional[str],
569
+ use_stealth: bool = False,
562
570
  ) -> Dict[str, Any]:
563
- """Render a web page using Playwright with async API."""
571
+ """Render a web page using Playwright with async API.
572
+
573
+ Args:
574
+ url (str): URL to render.
575
+ wait_time (int): Time to wait for JS execution.
576
+ wait_selector (Optional[str]): CSS selector to wait for.
577
+ scroll_to_bottom (bool): Whether to scroll to the bottom of the page.
578
+ screenshot (bool): Whether to take a screenshot.
579
+ screenshot_path (Optional[str]): Path to save the screenshot.
580
+ use_stealth (bool): Whether to use stealth mode to avoid bot detection.
581
+
582
+ Returns:
583
+ Dict[str, Any]: Rendered page content.
584
+ """
564
585
  from playwright.async_api import async_playwright
565
586
 
566
587
  async with async_playwright() as p:
@@ -569,6 +590,22 @@ class ScraperTool(BaseTool):
569
590
  user_agent=self.config.user_agent,
570
591
  viewport={"width": 1280, "height": 800},
571
592
  )
593
+
594
+ # Apply stealth mode if enabled
595
+ if use_stealth:
596
+ try:
597
+ from playwright_stealth import stealth_async
598
+ await stealth_async(page)
599
+ self.logger.info("Stealth mode enabled for Playwright")
600
+ except ImportError:
601
+ self.logger.warning(
602
+ "playwright-stealth is not installed. "
603
+ "Install it with 'pip install playwright-stealth' to use stealth mode. "
604
+ "Continuing without stealth mode."
605
+ )
606
+ except Exception as e:
607
+ self.logger.warning(f"Failed to apply stealth mode: {str(e)}. Continuing without stealth mode.")
608
+
572
609
  try:
573
610
  await page.goto(url)
574
611
  if wait_selector:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiecs
3
- Version: 1.7.17
3
+ Version: 1.8.4
4
4
  Summary: AI Execute Services - A middleware framework for AI-powered task execution and tool orchestration
5
5
  Author-email: AIECS Team <iretbl@gmail.com>
6
6
  License-Expression: MIT
@@ -48,7 +48,7 @@ Requires-Dist: langgraph<0.6.0,>=0.5.3
48
48
  Requires-Dist: weasel==0.4.1
49
49
  Requires-Dist: spacy<4.0.0,>=3.8.7
50
50
  Requires-Dist: rake-nltk<2.0.0,>=1.0.6
51
- Requires-Dist: numpy<3.0.0,>=2.2.6
51
+ Requires-Dist: numpy<3.0.0,>=2.4.1
52
52
  Requires-Dist: pandas<3.0.0,>=2.2.3
53
53
  Requires-Dist: scipy<2.0.0,>=1.15.3
54
54
  Requires-Dist: scikit-learn<2.0.0,>=1.5.0
@@ -105,6 +105,8 @@ Requires-Dist: sphinx-rtd-theme<3.0.0,>=2.0.0; extra == "docs"
105
105
  Requires-Dist: sphinx-autodoc-typehints<3.0.0,>=2.0.0; extra == "docs"
106
106
  Requires-Dist: myst-parser<3.0.0,>=2.0.0; extra == "docs"
107
107
  Requires-Dist: sphinx-copybutton<1.0.0,>=0.5.0; extra == "docs"
108
+ Provides-Extra: scraper
109
+ Requires-Dist: playwright-stealth<2.0.0,>=1.0.6; extra == "scraper"
108
110
  Dynamic: license-file
109
111
 
110
112
  # AIECS - AI Execute Services
@@ -1,7 +1,7 @@
1
- aiecs/__init__.py,sha256=E2PYbWAzU7vTEUbmirpTecpqae3VBiyuZsyNM2KQ3h0,1837
1
+ aiecs/__init__.py,sha256=ds9O4SZM1WtfWi6P9v356CyH94U05goAkzlv6XezMGQ,1836
2
2
  aiecs/__main__.py,sha256=SUsWL1jOdR3zv6yOi1dAdNH4wvzSVg07Vhlb6I9-bQY,1048
3
3
  aiecs/aiecs_client.py,sha256=CjSeiPZ9X0u6xkJcpVRXmCbIm0Wqyx3ejl7o7CaTzUI,18039
4
- aiecs/main.py,sha256=zYHFgadRkqvbzGBwargGVKHIxWDNm5EkMv3REMGiY6s,10722
4
+ aiecs/main.py,sha256=H7VzC04IaH7P-ucBJ8I8yq5afFptk-q4pvM5WOBCAUA,10720
5
5
  aiecs/application/__init__.py,sha256=NkmrUH1DqxJ3vaVC8QwscNdlWqHfC7ZagL4k3nZ_qz4,192
6
6
  aiecs/application/executors/__init__.py,sha256=WIl7L9HBsEhNfbNtJdvBvFUJXzESvNZVaiAA6tdtJcs,191
7
7
  aiecs/application/executors/operation_executor.py,sha256=WXPLnSYesTrkyVMd5HbOKG705k4eJiEV8200-ZSL0L8,14798
@@ -18,7 +18,7 @@ aiecs/application/knowledge_graph/builder/structured_pipeline.py,sha256=domjvcxK
18
18
  aiecs/application/knowledge_graph/builder/text_chunker.py,sha256=jvs4fxPocL_mobLPQqtqsk0Waub11EqUb1PIsLAbxZk,9567
19
19
  aiecs/application/knowledge_graph/extractors/__init__.py,sha256=FtCvr-R7CTDcEV4SqtUARoJ5OnULLhw26Ad4NRq8Cmg,705
20
20
  aiecs/application/knowledge_graph/extractors/base.py,sha256=XQisuU3UKteHqskqeV0uE_edz7-P03fgJyXDc1YqX1U,3336
21
- aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py,sha256=0hvZr1ozuf6_ld40OBo4CsDCGlc9Un0ejWIIv90IPrA,15263
21
+ aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py,sha256=dEV3xrCZ_r5PazT3wR4APaoybcyu1jDBuAkl3rQvO44,15400
22
22
  aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py,sha256=4OPvAjy_qj0NaVIA6c50cazu7ILOs_uBXXfcxJHOeM4,11484
23
23
  aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py,sha256=2yiGGK3tzjOD-ncMI_5_psKtJyLwpUQ-yuED8q3JZn0,7806
24
24
  aiecs/application/knowledge_graph/fusion/__init__.py,sha256=xQ30M8uhOx8-RV8eJ_Mzs2WhNYdu0piYmlncq_MluZ4,2217
@@ -57,7 +57,7 @@ aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py,sha256
57
57
  aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py,sha256=-WzYFryZTF_BB_P8NRBZztl_KRtyNtd6Hxz8JIm-Sto,12810
58
58
  aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py,sha256=xM9wk_h16TNCffWaqLE8K1LqewBtoTW709KAW3ZoRSw,6429
59
59
  aiecs/application/knowledge_graph/retrieval/__init__.py,sha256=pgbycGTCTo4rJQ2dWJrSENlVcf9y3kXpEIazqoJC83k,664
60
- aiecs/application/knowledge_graph/retrieval/query_intent_classifier.py,sha256=D0XK-oLYrvzv3-dzdD_NPkVm9IPUdJ9bvJKK8SctXvw,6808
60
+ aiecs/application/knowledge_graph/retrieval/query_intent_classifier.py,sha256=T5bCIM_ngLti29L6qsWIq9ClZhevvegoA8Zt7Uyyqr0,7003
61
61
  aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py,sha256=ya0HbnToPImGvgQyo8gZW_E9V8WX0J1cme8iJW68QZk,18626
62
62
  aiecs/application/knowledge_graph/retrieval/strategy_types.py,sha256=HI7yhC1bTD76TtQodk0cQpNO5285IxRkdD_K0p7BlHU,706
63
63
  aiecs/application/knowledge_graph/search/__init__.py,sha256=3-c89qUNQq9qcRofVPQanOnKO7G1PEAemJPm98ZRGx4,1471
@@ -76,7 +76,7 @@ aiecs/common/__init__.py,sha256=6XzlzbA5JU8sFIAEF9-MZTGCbksTqCickXqEITT6cpI,116
76
76
  aiecs/common/knowledge_graph/__init__.py,sha256=RBvTWuB_PzolXDYBAdqJrFYpQV34VGW0v21t4Bja8Uo,294
77
77
  aiecs/common/knowledge_graph/runnable.py,sha256=BLsV9HHfO4lT3_LkFQbf_rUT_iXloZi4D-ztwFqVNuY,15233
78
78
  aiecs/config/__init__.py,sha256=aQk0xVquxBZmLTol8wvF4Jv8Yl9G6qyMvA1RL_JE99k,974
79
- aiecs/config/config.py,sha256=jI5d4xLbU-7NoUcQIydpB9CCKUFyXElJt_OENaHGy_8,33657
79
+ aiecs/config/config.py,sha256=FzBVG7ZZ7Nq6shbEEL8Hf9XzNbgr7axl9cZkUi_7GZk,33895
80
80
  aiecs/config/graph_config.py,sha256=9-Xrgd1kswfoIep5nzKmVhEz2vPENqtm_l9nZkXLXL0,3993
81
81
  aiecs/config/tool_config.py,sha256=iuMBlHlNWoXzcXxVaGuU1BOruh0yQbAZtPTrAqkNPkQ,16301
82
82
  aiecs/core/__init__.py,sha256=WnY-iEE0BpdRg26vVSCILvERzcXg6kajS4IiO2-NovI,1471
@@ -90,10 +90,10 @@ aiecs/domain/agent/__init__.py,sha256=yMDE7r_z8EHGmteWc4E9JoNBVRgeR72VNU7p3c5Obl
90
90
  aiecs/domain/agent/base_agent.py,sha256=r6jn8Ux9FswRAYXSx8IrsB_SigeCC5VebPLCb7OmJMk,148078
91
91
  aiecs/domain/agent/exceptions.py,sha256=axBRJebHP_JpMfjDstOGRxRXsvPXpmZ78Tccv5TxUs0,2951
92
92
  aiecs/domain/agent/graph_aware_mixin.py,sha256=1LScf_JuAU67JtuUgoL7DRCQ6WNJA66-U7AXdgEms1Q,18665
93
- aiecs/domain/agent/hybrid_agent.py,sha256=EmuAqUZvlPiquMhHiAEsG0N9ZEi3qqhNXGj5rVlfDD4,72468
94
- aiecs/domain/agent/knowledge_aware_agent.py,sha256=xkCY12RFK1cNwrRdFGIOKkX6BuwBFO0jIjRRCCsn-ew,74013
93
+ aiecs/domain/agent/hybrid_agent.py,sha256=CAIR6CO9orQmRfjJdxMAEdlaSh0WQoGbr23tlBcP4zg,76325
94
+ aiecs/domain/agent/knowledge_aware_agent.py,sha256=YuIz1nhZUYwH5yGQq0c71d_LFgNNsYMxiVR0g9g2JLA,74096
95
95
  aiecs/domain/agent/lifecycle.py,sha256=Mqi0YJYBsTfsD-NC0EZOA1Di889qrnRPzQAehxZO32M,8719
96
- aiecs/domain/agent/llm_agent.py,sha256=Aj6MvoiKTC8Qxfm6JtCruz77onLa5qUah98SituU8XU,24592
96
+ aiecs/domain/agent/llm_agent.py,sha256=B0RFbchi8QgJHX-VcypOtCLLqyD2DRFPamljB4L9nKY,24658
97
97
  aiecs/domain/agent/models.py,sha256=c7cgW5Oydw86zcfT39CctByWTuZk2FpvWLFjpWjd9pw,36751
98
98
  aiecs/domain/agent/observability.py,sha256=BjCzX0f7GJkusEYsYrVZKFXuIoRO9kH3wgVgHb-W5T0,13806
99
99
  aiecs/domain/agent/persistence.py,sha256=Qfd8LWR9am4vueJp5eAjjBKuPxlbGsOScSQkUbIwt84,14399
@@ -195,24 +195,26 @@ aiecs/infrastructure/persistence/database_manager.py,sha256=Oe8Sl-itZBs7bGKcM_50
195
195
  aiecs/infrastructure/persistence/file_storage.py,sha256=4cZ8AbPMdajfJHUL8ZnuVuLRm7gW74HNQl1fUyfJ90A,26838
196
196
  aiecs/infrastructure/persistence/redis_client.py,sha256=oL2C2wmDJC5lFpTEfPle7a1-lvP-3TBxPTIyrskpTlk,7569
197
197
  aiecs/llm/__init__.py,sha256=vLn52v1LQgz75iZy6CvTb_vq5rMYbpZFZMFPKxJV-1k,2183
198
- aiecs/llm/client_factory.py,sha256=in7ZyKxHHdz1jqD8jA0TOeZoT9VRE0M8NC4j97JFTGA,20031
198
+ aiecs/llm/client_factory.py,sha256=gij-1cXXVRRhZZ7X3RRQK5Wj5rD3sNxCDiJiulbwUjU,20389
199
199
  aiecs/llm/client_resolver.py,sha256=rRyHYajOk6YpsTRJJW6Y2FwWwpJLe0b77ncaJXX2fwU,5075
200
- aiecs/llm/protocols.py,sha256=8Qj7ryOGQ07_j5Xd-UHsIU9wiBU1BxLE-tdzf_bj__4,4516
200
+ aiecs/llm/protocols.py,sha256=PVS-MkS_bmm2FvGXk-NFMqNVbEVPOwNonvSEim3A6N0,5684
201
201
  aiecs/llm/callbacks/__init__.py,sha256=u02K5Tvlu-87NXxYzXuxFHuhHAF4OPIje_IvPIF93Lw,191
202
- aiecs/llm/callbacks/custom_callbacks.py,sha256=g87NK2Zpgvpd_-6PLRFG_fTgIYqGucWL_xEnuU3Kq0g,9904
202
+ aiecs/llm/callbacks/custom_callbacks.py,sha256=RFonkZSpgEDgCZ4GhFCLVa7MGBfTddwMGnmmcid-otc,10164
203
203
  aiecs/llm/clients/__init__.py,sha256=GaUkYc0mnKrsBceGrjDZ3K6LZUVxGxHqxjB9zSxWRq8,822
204
- aiecs/llm/clients/base_client.py,sha256=8L3C9dK3-cHqVCLGISBZIA89j36HM_2G5mhpmvTskbY,11144
204
+ aiecs/llm/clients/base_client.py,sha256=X_wILA3bxftatMQ2FBAzT922-9SwaHRfBpJvCGwi-ig,13103
205
205
  aiecs/llm/clients/google_function_calling_mixin.py,sha256=od9-kgnhKtqJc_b-M0Xi2VGAlu8QwGR5MyXt0XpoxdM,16636
206
- aiecs/llm/clients/googleai_client.py,sha256=c5tPbKQS8JVE687CYP_izStf4x0upgyyBT6eNmXOqcQ,12039
207
- aiecs/llm/clients/openai_client.py,sha256=sgrYM7KGfCKNOe-wtz3fwVhG27VqYCvnz2hQggt12oM,5582
208
- aiecs/llm/clients/openai_compatible_mixin.py,sha256=uJfycFcDF8Zlv5x2xAVVB0n6mUND4IcJ1pEInaxHB1s,14463
209
- aiecs/llm/clients/vertex_client.py,sha256=z-3bfsS9yyZwKyyC5159PmzWMlYMscSHx7nKD8Pq1Bk,54527
210
- aiecs/llm/clients/xai_client.py,sha256=mJW8hV12FcJtI8nhU34NV-by5o4Xhzv-Ua3Go8ET1kQ,7172
206
+ aiecs/llm/clients/googleai_client.py,sha256=-DM2V8RaoXLoAG7hH0j56LnCvWrhI3pRv56VaQXKb3Y,17107
207
+ aiecs/llm/clients/openai_client.py,sha256=LacvKQlxEcoN7TWuRvBNTz4mM2JhVBdz8lk9ZNB3LL4,6328
208
+ aiecs/llm/clients/openai_compatible_mixin.py,sha256=51tvJQCi-GgDJNN-V_1iTe-N1xFqmd0A5kR1w-udcJc,16224
209
+ aiecs/llm/clients/openrouter_client.py,sha256=bN4aaicZHYv7UHoT4L7_7HhZcNf854DAbaSp2A67-Gg,10357
210
+ aiecs/llm/clients/vertex_client.py,sha256=9yRDvrR9KIt5_K0u9xk-ZwrxUNDmzpePcvEwf5__yNs,58147
211
+ aiecs/llm/clients/xai_client.py,sha256=e76ZuwnLZ4t1zjGtnnyTAm_8lE2VJyaqG1Pgh6uK74E,9162
211
212
  aiecs/llm/config/__init__.py,sha256=LCPZXrV4-zUMh6IS32WaUBMT43pSF8dqbhqH3xBcwJU,1107
212
213
  aiecs/llm/config/config_loader.py,sha256=Jhd6y4FyMQO73Mwv45Qq--pmPh8XRAzbVxi1xqAgWF8,8653
213
214
  aiecs/llm/config/config_validator.py,sha256=6pXxn7O8wSdoWf3zJdmCbufqR-ojWlDKaYrkly55D9Y,7235
214
215
  aiecs/llm/config/model_config.py,sha256=ZlUmjlhS_U_BdRe3Y3Zk5M1029ctXHBSwdYqF07H_z8,5687
215
216
  aiecs/llm/utils/__init__.py,sha256=zKlDyNjvJsv5URW0B1g4C9cimuB7jmKkcfxkLsTAOVY,239
217
+ aiecs/llm/utils/image_utils.py,sha256=yBuc1vH6YS4DIb7R3zL7ofUItgJzeOJw5S_CC8v70-Y,5744
216
218
  aiecs/llm/utils/validate_config.py,sha256=lfi30kPSWoFqDfZvbZTjQfBWMvupBpDh_CzHfDKU3Sw,2959
217
219
  aiecs/scripts/__init__.py,sha256=cVxQ5iqym520eDQSpV7B6hWolndCLMOVdvhC_D280PE,66
218
220
  aiecs/scripts/aid/VERSION_MANAGEMENT.md,sha256=e0ZL0-ou9R6TW1U4QXNDNfiXVjK6m6SDub9KuJzu98Y,3162
@@ -315,7 +317,7 @@ aiecs/tools/task_tools/office_tool.py,sha256=0Nw5ppP9sXnnk65yVt9BQYy3Nil8Td33N6u
315
317
  aiecs/tools/task_tools/pandas_tool.py,sha256=5MHoVz24p178xBZPhIo_dsiej4645jmZvEiy_i0e1mo,41832
316
318
  aiecs/tools/task_tools/report_tool.py,sha256=8vIoFLfQvmOjUhFoht2tyZ5Wq7DqsPfXvx0lzORnxs0,34934
317
319
  aiecs/tools/task_tools/research_tool.py,sha256=comD38XNHMwrQyGYuP5KWVeobF4inN2o3JCPsox6ixE,19198
318
- aiecs/tools/task_tools/scraper_tool.py,sha256=Z_yY7b3bNYe_BEUPVy9d9DlagdhMv9bleC762bFK2L8,29538
320
+ aiecs/tools/task_tools/scraper_tool.py,sha256=LXEp7IOBaiyfsrUyLzk8MZpK3yXKqssmsxGI7AVQgAk,31281
319
321
  aiecs/tools/task_tools/stats_tool.py,sha256=f_PrPgOOiJXpW-aA9_hXhyhpW7D2-QkPjnYF0Duh7tg,33563
320
322
  aiecs/tools/tool_executor/__init__.py,sha256=sR2ss7Ep7OKSu0d0566rd14DDkH3tkYmbMLxpEs6kO8,783
321
323
  aiecs/tools/tool_executor/tool_executor.py,sha256=WrQMwiiVi-GM8o41zIcT8hUZzvcOXdAhOenBPe998sw,30387
@@ -329,9 +331,9 @@ aiecs/utils/prompt_loader.py,sha256=iNBNeUSnvbSE1SrllOlBllDdQXtfzq5dO5rjkcFEsSw,
329
331
  aiecs/utils/token_usage_repository.py,sha256=gFTu-AHawFmScq35T3ib5pTElZrXezu3ijxRRCxW6vc,10497
330
332
  aiecs/ws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
331
333
  aiecs/ws/socket_server.py,sha256=4jJBx93DEOKs2JO-gZAH9R_MfMTVtLLTLtyYnRyCVew,1591
332
- aiecs-1.7.17.dist-info/licenses/LICENSE,sha256=_1YRaIS0eZu1pv6xfz245UkU0i1Va2B841hv3OWRwqg,12494
333
- aiecs-1.7.17.dist-info/METADATA,sha256=EJfH7jPBLmDasjx0k48dHRWQmtb6iNhwxlPSbFntMXQ,18101
334
- aiecs-1.7.17.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
335
- aiecs-1.7.17.dist-info/entry_points.txt,sha256=t_mIkFuLDmK-2si0thMfgK0WIBg-Ub94V3MchpWMaAs,899
336
- aiecs-1.7.17.dist-info/top_level.txt,sha256=22IlUlOqh9Ni3jXlQNMNUqzbW8dcxXPeR_EQ-BJVcV8,6
337
- aiecs-1.7.17.dist-info/RECORD,,
334
+ aiecs-1.8.4.dist-info/licenses/LICENSE,sha256=_1YRaIS0eZu1pv6xfz245UkU0i1Va2B841hv3OWRwqg,12494
335
+ aiecs-1.8.4.dist-info/METADATA,sha256=kb1vMbolQckKE0Mu2hmpsgjB6DZ4fCauGypdgPsETF0,18192
336
+ aiecs-1.8.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
337
+ aiecs-1.8.4.dist-info/entry_points.txt,sha256=t_mIkFuLDmK-2si0thMfgK0WIBg-Ub94V3MchpWMaAs,899
338
+ aiecs-1.8.4.dist-info/top_level.txt,sha256=22IlUlOqh9Ni3jXlQNMNUqzbW8dcxXPeR_EQ-BJVcV8,6
339
+ aiecs-1.8.4.dist-info/RECORD,,
File without changes