aiecs 1.7.6__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.
- aiecs/__init__.py +1 -1
- aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +5 -1
- aiecs/application/knowledge_graph/retrieval/query_intent_classifier.py +7 -5
- aiecs/config/config.py +3 -0
- aiecs/config/tool_config.py +55 -19
- aiecs/domain/agent/base_agent.py +79 -0
- aiecs/domain/agent/hybrid_agent.py +552 -175
- aiecs/domain/agent/knowledge_aware_agent.py +3 -2
- aiecs/domain/agent/llm_agent.py +2 -0
- aiecs/domain/agent/models.py +10 -0
- aiecs/domain/agent/tools/schema_generator.py +17 -4
- aiecs/llm/callbacks/custom_callbacks.py +9 -4
- aiecs/llm/client_factory.py +20 -7
- aiecs/llm/clients/base_client.py +50 -5
- aiecs/llm/clients/google_function_calling_mixin.py +46 -88
- aiecs/llm/clients/googleai_client.py +183 -9
- aiecs/llm/clients/openai_client.py +12 -0
- aiecs/llm/clients/openai_compatible_mixin.py +42 -2
- aiecs/llm/clients/openrouter_client.py +272 -0
- aiecs/llm/clients/vertex_client.py +385 -22
- aiecs/llm/clients/xai_client.py +41 -3
- aiecs/llm/protocols.py +19 -1
- aiecs/llm/utils/image_utils.py +179 -0
- aiecs/main.py +2 -2
- aiecs/tools/docs/document_creator_tool.py +143 -2
- aiecs/tools/docs/document_parser_tool.py +9 -4
- aiecs/tools/docs/document_writer_tool.py +179 -0
- aiecs/tools/task_tools/image_tool.py +49 -14
- aiecs/tools/task_tools/scraper_tool.py +39 -2
- {aiecs-1.7.6.dist-info → aiecs-1.8.4.dist-info}/METADATA +4 -2
- {aiecs-1.7.6.dist-info → aiecs-1.8.4.dist-info}/RECORD +35 -33
- {aiecs-1.7.6.dist-info → aiecs-1.8.4.dist-info}/WHEEL +0 -0
- {aiecs-1.7.6.dist-info → aiecs-1.8.4.dist-info}/entry_points.txt +0 -0
- {aiecs-1.7.6.dist-info → aiecs-1.8.4.dist-info}/licenses/LICENSE +0 -0
- {aiecs-1.7.6.dist-info → aiecs-1.8.4.dist-info}/top_level.txt +0 -0
|
@@ -32,6 +32,8 @@ class DocumentFormat(str, Enum):
|
|
|
32
32
|
PDF = "pdf"
|
|
33
33
|
DOCX = "docx"
|
|
34
34
|
XLSX = "xlsx"
|
|
35
|
+
PPTX = "pptx"
|
|
36
|
+
PPT = "ppt"
|
|
35
37
|
BINARY = "binary"
|
|
36
38
|
|
|
37
39
|
|
|
@@ -214,6 +216,9 @@ class DocumentWriterTool(BaseTool):
|
|
|
214
216
|
# Initialize cloud storage
|
|
215
217
|
self._init_cloud_storage()
|
|
216
218
|
|
|
219
|
+
# Initialize office tool for PPTX/DOCX writing
|
|
220
|
+
self._init_office_tool()
|
|
221
|
+
|
|
217
222
|
# Initialize content validators
|
|
218
223
|
self._init_validators()
|
|
219
224
|
|
|
@@ -260,6 +265,17 @@ class DocumentWriterTool(BaseTool):
|
|
|
260
265
|
self.logger.warning(f"Cloud storage initialization failed: {e}")
|
|
261
266
|
self.file_storage = None
|
|
262
267
|
|
|
268
|
+
def _init_office_tool(self):
|
|
269
|
+
"""Initialize office tool for PPTX/DOCX writing"""
|
|
270
|
+
try:
|
|
271
|
+
from aiecs.tools.task_tools.office_tool import OfficeTool
|
|
272
|
+
|
|
273
|
+
self.office_tool = OfficeTool()
|
|
274
|
+
self.logger.info("OfficeTool initialized successfully for PPTX/DOCX support")
|
|
275
|
+
except ImportError:
|
|
276
|
+
self.logger.warning("OfficeTool not available, PPTX/DOCX writing will be limited")
|
|
277
|
+
self.office_tool = None
|
|
278
|
+
|
|
263
279
|
def _init_validators(self):
|
|
264
280
|
"""Initialize content validators"""
|
|
265
281
|
self.validators = {
|
|
@@ -722,6 +738,14 @@ class DocumentWriterTool(BaseTool):
|
|
|
722
738
|
"""Write to local file system with atomic operation"""
|
|
723
739
|
|
|
724
740
|
try:
|
|
741
|
+
# Handle PPTX format using office_tool
|
|
742
|
+
if format in [DocumentFormat.PPTX, DocumentFormat.PPT]:
|
|
743
|
+
return self._write_pptx_file(target_path, content, plan)
|
|
744
|
+
|
|
745
|
+
# Handle DOCX format using office_tool
|
|
746
|
+
if format == DocumentFormat.DOCX:
|
|
747
|
+
return self._write_docx_file(target_path, content, plan)
|
|
748
|
+
|
|
725
749
|
# Create parent directories
|
|
726
750
|
os.makedirs(os.path.dirname(target_path), exist_ok=True)
|
|
727
751
|
|
|
@@ -789,6 +813,161 @@ class DocumentWriterTool(BaseTool):
|
|
|
789
813
|
except Exception as e:
|
|
790
814
|
raise StorageError(f"Local file write failed: {e}")
|
|
791
815
|
|
|
816
|
+
def _write_pptx_file(self, target_path: str, content: Union[str, bytes], plan: Dict) -> Dict:
|
|
817
|
+
"""Write content to PPTX file using office_tool"""
|
|
818
|
+
if not self.office_tool:
|
|
819
|
+
raise StorageError("OfficeTool not available. Cannot write PPTX files.")
|
|
820
|
+
|
|
821
|
+
try:
|
|
822
|
+
# Convert bytes to string if needed
|
|
823
|
+
if isinstance(content, bytes):
|
|
824
|
+
content_str = content.decode("utf-8")
|
|
825
|
+
else:
|
|
826
|
+
content_str = str(content)
|
|
827
|
+
|
|
828
|
+
# Parse content to extract slides
|
|
829
|
+
slides = self._parse_content_to_slides(content_str)
|
|
830
|
+
|
|
831
|
+
# Handle append mode
|
|
832
|
+
if plan["mode"] == WriteMode.APPEND and plan["file_exists"]:
|
|
833
|
+
# Read existing slides
|
|
834
|
+
existing_slides = self.office_tool.read_pptx(target_path)
|
|
835
|
+
slides = existing_slides + slides
|
|
836
|
+
|
|
837
|
+
# Use office_tool to write PPTX
|
|
838
|
+
result = self.office_tool.write_pptx(
|
|
839
|
+
slides=slides,
|
|
840
|
+
output_path=target_path,
|
|
841
|
+
image_path=None,
|
|
842
|
+
)
|
|
843
|
+
|
|
844
|
+
if not result.get("success"):
|
|
845
|
+
raise StorageError(f"Failed to write PPTX file: {result}")
|
|
846
|
+
|
|
847
|
+
# Get file stats
|
|
848
|
+
stat = os.stat(target_path)
|
|
849
|
+
|
|
850
|
+
return {
|
|
851
|
+
"path": target_path,
|
|
852
|
+
"size": stat.st_size,
|
|
853
|
+
"checksum": self._calculate_file_checksum(target_path),
|
|
854
|
+
"modified_time": datetime.fromtimestamp(stat.st_mtime).isoformat(),
|
|
855
|
+
"atomic_write": False, # Office tool handles its own atomicity
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
except Exception as e:
|
|
859
|
+
raise StorageError(f"PPTX file write failed: {e}")
|
|
860
|
+
|
|
861
|
+
def _write_docx_file(self, target_path: str, content: Union[str, bytes], plan: Dict) -> Dict:
|
|
862
|
+
"""Write content to DOCX file using office_tool"""
|
|
863
|
+
if not self.office_tool:
|
|
864
|
+
raise StorageError("OfficeTool not available. Cannot write DOCX files.")
|
|
865
|
+
|
|
866
|
+
try:
|
|
867
|
+
# Convert bytes to string if needed
|
|
868
|
+
if isinstance(content, bytes):
|
|
869
|
+
content_str = content.decode("utf-8")
|
|
870
|
+
else:
|
|
871
|
+
content_str = str(content)
|
|
872
|
+
|
|
873
|
+
# Handle append mode
|
|
874
|
+
if plan["mode"] == WriteMode.APPEND and plan["file_exists"]:
|
|
875
|
+
# Read existing content
|
|
876
|
+
existing_doc = self.office_tool.read_docx(target_path)
|
|
877
|
+
existing_text = "\n".join(existing_doc.get("paragraphs", []))
|
|
878
|
+
content_str = existing_text + "\n" + content_str
|
|
879
|
+
|
|
880
|
+
# Use office_tool to write DOCX
|
|
881
|
+
result = self.office_tool.write_docx(
|
|
882
|
+
text=content_str,
|
|
883
|
+
output_path=target_path,
|
|
884
|
+
table_data=None,
|
|
885
|
+
)
|
|
886
|
+
|
|
887
|
+
if not result.get("success"):
|
|
888
|
+
raise StorageError(f"Failed to write DOCX file: {result}")
|
|
889
|
+
|
|
890
|
+
# Get file stats
|
|
891
|
+
stat = os.stat(target_path)
|
|
892
|
+
|
|
893
|
+
return {
|
|
894
|
+
"path": target_path,
|
|
895
|
+
"size": stat.st_size,
|
|
896
|
+
"checksum": self._calculate_file_checksum(target_path),
|
|
897
|
+
"modified_time": datetime.fromtimestamp(stat.st_mtime).isoformat(),
|
|
898
|
+
"atomic_write": False, # Office tool handles its own atomicity
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
except Exception as e:
|
|
902
|
+
raise StorageError(f"DOCX file write failed: {e}")
|
|
903
|
+
|
|
904
|
+
def _parse_content_to_slides(self, content: str) -> List[str]:
|
|
905
|
+
"""Parse content string into list of slide contents
|
|
906
|
+
|
|
907
|
+
Supports multiple slide separation formats:
|
|
908
|
+
- "---" separator (markdown style)
|
|
909
|
+
- "## Slide X:" headers
|
|
910
|
+
- Empty lines between slides
|
|
911
|
+
"""
|
|
912
|
+
slides = []
|
|
913
|
+
|
|
914
|
+
# Split by "---" separator (common in markdown presentations)
|
|
915
|
+
if "---" in content:
|
|
916
|
+
parts = content.split("---")
|
|
917
|
+
for part in parts:
|
|
918
|
+
part = part.strip()
|
|
919
|
+
if part:
|
|
920
|
+
# Remove slide headers like "## Slide X: Title"
|
|
921
|
+
lines = part.split("\n")
|
|
922
|
+
cleaned_lines = []
|
|
923
|
+
for line in lines:
|
|
924
|
+
# Skip slide headers
|
|
925
|
+
if line.strip().startswith("## Slide") and ":" in line:
|
|
926
|
+
continue
|
|
927
|
+
cleaned_lines.append(line)
|
|
928
|
+
slide_content = "\n".join(cleaned_lines).strip()
|
|
929
|
+
if slide_content:
|
|
930
|
+
slides.append(slide_content)
|
|
931
|
+
else:
|
|
932
|
+
# Try to split by "## Slide" headers
|
|
933
|
+
if "## Slide" in content:
|
|
934
|
+
parts = content.split("## Slide")
|
|
935
|
+
for i, part in enumerate(parts):
|
|
936
|
+
if i == 0:
|
|
937
|
+
# First part might be title slide
|
|
938
|
+
part = part.strip()
|
|
939
|
+
if part:
|
|
940
|
+
slides.append(part)
|
|
941
|
+
else:
|
|
942
|
+
# Extract content after "Slide X: Title"
|
|
943
|
+
lines = part.split("\n", 1)
|
|
944
|
+
if len(lines) > 1:
|
|
945
|
+
slide_content = lines[1].strip()
|
|
946
|
+
if slide_content:
|
|
947
|
+
slides.append(slide_content)
|
|
948
|
+
else:
|
|
949
|
+
# Fallback: split by double newlines (paragraph breaks)
|
|
950
|
+
parts = content.split("\n\n")
|
|
951
|
+
current_slide = []
|
|
952
|
+
for part in parts:
|
|
953
|
+
part = part.strip()
|
|
954
|
+
if part:
|
|
955
|
+
# If it's a header, start a new slide
|
|
956
|
+
if part.startswith("#"):
|
|
957
|
+
if current_slide:
|
|
958
|
+
slides.append("\n".join(current_slide))
|
|
959
|
+
current_slide = []
|
|
960
|
+
current_slide.append(part)
|
|
961
|
+
|
|
962
|
+
if current_slide:
|
|
963
|
+
slides.append("\n".join(current_slide))
|
|
964
|
+
|
|
965
|
+
# If no slides found, create a single slide with all content
|
|
966
|
+
if not slides:
|
|
967
|
+
slides = [content.strip()] if content.strip() else [""]
|
|
968
|
+
|
|
969
|
+
return slides
|
|
970
|
+
|
|
792
971
|
async def _write_to_cloud_storage(
|
|
793
972
|
self,
|
|
794
973
|
target_path: str,
|
|
@@ -148,6 +148,10 @@ class ImageTool(BaseTool):
|
|
|
148
148
|
description="Allowed image file extensions",
|
|
149
149
|
)
|
|
150
150
|
tesseract_pool_size: int = Field(default=2, description="Number of Tesseract processes for OCR")
|
|
151
|
+
default_ocr_language: str = Field(
|
|
152
|
+
default="eng",
|
|
153
|
+
description="Default OCR language code (e.g., 'eng', 'chi_sim'). Supports multi-language format like 'eng+chi_sim'"
|
|
154
|
+
)
|
|
151
155
|
|
|
152
156
|
# Schema definitions
|
|
153
157
|
class LoadSchema(BaseFileSchema):
|
|
@@ -159,7 +163,10 @@ class ImageTool(BaseTool):
|
|
|
159
163
|
"""Schema for ocr operation"""
|
|
160
164
|
|
|
161
165
|
file_path: str = Field(description="Path to the image file for OCR text extraction")
|
|
162
|
-
lang: Optional[str] = Field(
|
|
166
|
+
lang: Optional[str] = Field(
|
|
167
|
+
default=None,
|
|
168
|
+
description="Optional language code for OCR (e.g., 'eng', 'chi_sim', 'eng+chi_sim'). If not specified, uses the configured default_ocr_language"
|
|
169
|
+
)
|
|
163
170
|
|
|
164
171
|
class MetadataSchema(BaseFileSchema):
|
|
165
172
|
"""Schema for metadata operation"""
|
|
@@ -228,10 +235,16 @@ class ImageTool(BaseTool):
|
|
|
228
235
|
|
|
229
236
|
Configuration is automatically loaded by BaseTool from:
|
|
230
237
|
1. Explicit config dict (highest priority)
|
|
231
|
-
2. YAML config files (config/tools/image.yaml)
|
|
232
|
-
3. Environment variables (via dotenv from .env files)
|
|
238
|
+
2. YAML config files (config/tools/image.yaml, config/tools/image_tool.yaml, or config/tools/ImageTool.yaml)
|
|
239
|
+
3. Environment variables (via dotenv from .env files with IMAGE_TOOL_ prefix)
|
|
233
240
|
4. Tool defaults (lowest priority)
|
|
241
|
+
|
|
242
|
+
YAML configuration files are automatically discovered by ToolConfigLoader using multiple naming conventions.
|
|
243
|
+
See examples/config/tools/image_tool.yaml.example for a configuration template.
|
|
234
244
|
"""
|
|
245
|
+
# Pass tool_name="image" to BaseTool so it can find config/tools/image.yaml
|
|
246
|
+
if "tool_name" not in kwargs:
|
|
247
|
+
kwargs["tool_name"] = "image"
|
|
235
248
|
super().__init__(config, **kwargs)
|
|
236
249
|
|
|
237
250
|
# Configuration is automatically loaded by BaseTool into self._config_obj
|
|
@@ -298,11 +311,12 @@ class ImageTool(BaseTool):
|
|
|
298
311
|
|
|
299
312
|
def ocr(self, file_path: str, lang: Optional[str] = None) -> str:
|
|
300
313
|
"""
|
|
301
|
-
Extract text from an image using
|
|
314
|
+
Extract text from an image using Tesseract OCR.
|
|
302
315
|
|
|
303
316
|
Args:
|
|
304
317
|
file_path (str): Path to the image file.
|
|
305
|
-
lang (Optional[str]): Language code for OCR (e.g., 'eng').
|
|
318
|
+
lang (Optional[str]): Language code for OCR (e.g., 'eng', 'chi_sim', 'eng+chi_sim').
|
|
319
|
+
If not specified, uses the configured default_ocr_language.
|
|
306
320
|
|
|
307
321
|
Returns:
|
|
308
322
|
str: Extracted text.
|
|
@@ -312,23 +326,44 @@ class ImageTool(BaseTool):
|
|
|
312
326
|
"""
|
|
313
327
|
# Validate input using schema
|
|
314
328
|
validated_input = self.OcrSchema(file_path=file_path, lang=lang)
|
|
329
|
+
|
|
330
|
+
# Use configured default language if lang is not specified
|
|
331
|
+
ocr_lang = lang if lang is not None else self.config.default_ocr_language
|
|
315
332
|
|
|
316
|
-
|
|
317
|
-
if not proc:
|
|
318
|
-
raise FileOperationError(f"ocr: No Tesseract processes available (lang: {lang or 'eng'})")
|
|
333
|
+
# Prepare temporary file for image processing
|
|
319
334
|
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as temp_file:
|
|
320
335
|
temp_path = temp_file.name
|
|
321
336
|
try:
|
|
337
|
+
# Preprocess image for better OCR results
|
|
322
338
|
img = Image.open(validated_input.file_path).convert("L").filter(ImageFilter.SHARPEN)
|
|
323
339
|
img.save(temp_path)
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
340
|
+
|
|
341
|
+
# Call Tesseract with dynamic language parameter
|
|
342
|
+
# Use subprocess.run instead of process pool to support dynamic languages
|
|
343
|
+
try:
|
|
344
|
+
result = subprocess.run(
|
|
345
|
+
["tesseract", "--oem", "1", temp_path, "stdout", "-l", ocr_lang],
|
|
346
|
+
capture_output=True,
|
|
347
|
+
text=True,
|
|
348
|
+
timeout=30,
|
|
349
|
+
check=False, # Don't raise on non-zero return code, handle manually
|
|
350
|
+
)
|
|
351
|
+
except subprocess.TimeoutExpired:
|
|
352
|
+
raise FileOperationError(f"ocr: Tesseract timeout for '{file_path}' (lang: {ocr_lang})")
|
|
353
|
+
except FileNotFoundError:
|
|
354
|
+
raise FileOperationError("ocr: Tesseract not found. Please install Tesseract OCR.")
|
|
355
|
+
|
|
356
|
+
if result.returncode != 0:
|
|
357
|
+
raise FileOperationError(
|
|
358
|
+
f"ocr: Tesseract failed for '{file_path}' (lang: {ocr_lang}): {result.stderr}"
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
return result.stdout.strip()
|
|
362
|
+
except FileOperationError:
|
|
363
|
+
raise # Re-raise FileOperationError as-is
|
|
328
364
|
except Exception as e:
|
|
329
|
-
raise FileOperationError(f"ocr: Failed to process '{file_path}' (lang: {
|
|
365
|
+
raise FileOperationError(f"ocr: Failed to process '{file_path}' (lang: {ocr_lang}): {e}")
|
|
330
366
|
finally:
|
|
331
|
-
self._tesseract_manager.return_process(proc)
|
|
332
367
|
if os.path.exists(temp_path):
|
|
333
368
|
try:
|
|
334
369
|
os.unlink(temp_path)
|
|
@@ -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.
|
|
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.
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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,9 +76,9 @@ 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=
|
|
79
|
+
aiecs/config/config.py,sha256=FzBVG7ZZ7Nq6shbEEL8Hf9XzNbgr7axl9cZkUi_7GZk,33895
|
|
80
80
|
aiecs/config/graph_config.py,sha256=9-Xrgd1kswfoIep5nzKmVhEz2vPENqtm_l9nZkXLXL0,3993
|
|
81
|
-
aiecs/config/tool_config.py,sha256=
|
|
81
|
+
aiecs/config/tool_config.py,sha256=iuMBlHlNWoXzcXxVaGuU1BOruh0yQbAZtPTrAqkNPkQ,16301
|
|
82
82
|
aiecs/core/__init__.py,sha256=WnY-iEE0BpdRg26vVSCILvERzcXg6kajS4IiO2-NovI,1471
|
|
83
83
|
aiecs/core/interface/__init__.py,sha256=BwngZE6IqA7UBql71C5mCgVhfzmDtdZKFM7Dd3KIlTM,690
|
|
84
84
|
aiecs/core/interface/execution_interface.py,sha256=4_aqjLPhPvLFq-EsVHLlzlLJw6IoKw49fv8Zeh3iMpY,4618
|
|
@@ -87,14 +87,14 @@ aiecs/core/registry/__init__.py,sha256=Dd0UspDS1RLCIawmKN8w9rQa4Nx-vVE6yHNhGEMne
|
|
|
87
87
|
aiecs/core/registry/service_registry.py,sha256=RqKh4C7X3TJlJRBiT9tNZnwFIcXux05BSPTG6Mxswus,2445
|
|
88
88
|
aiecs/domain/__init__.py,sha256=hRyDL-WbPk16S0abxtMdPY0vzU3qaHRV2REYRo_fHiU,6854
|
|
89
89
|
aiecs/domain/agent/__init__.py,sha256=yMDE7r_z8EHGmteWc4E9JoNBVRgeR72VNU7p3c5Oblg,4084
|
|
90
|
-
aiecs/domain/agent/base_agent.py,sha256=
|
|
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=
|
|
94
|
-
aiecs/domain/agent/knowledge_aware_agent.py,sha256=
|
|
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=
|
|
97
|
-
aiecs/domain/agent/models.py,sha256=
|
|
96
|
+
aiecs/domain/agent/llm_agent.py,sha256=B0RFbchi8QgJHX-VcypOtCLLqyD2DRFPamljB4L9nKY,24658
|
|
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
|
|
100
100
|
aiecs/domain/agent/registry.py,sha256=IvPJeFi7PY2Av8qzywGqhLmycR96k5PA8YVCVxnKvqg,6841
|
|
@@ -115,7 +115,7 @@ aiecs/domain/agent/prompts/builder.py,sha256=uWkuBbLSk1leQu4Lx82_gZQ1CxlOFZOevgg
|
|
|
115
115
|
aiecs/domain/agent/prompts/formatters.py,sha256=VuH42B02TUM5EP0aEyXVbdwD3xhuDQvsFpFz1R7s61c,4596
|
|
116
116
|
aiecs/domain/agent/prompts/template.py,sha256=5hLTJKGUa9I1DTsfL7HhErG1wXTe18jVBanCXqYUL2U,7365
|
|
117
117
|
aiecs/domain/agent/tools/__init__.py,sha256=fdeZxTqlimXuDjAoEEKmYRXhQK3Gyba2rIDU4JE2jVE,239
|
|
118
|
-
aiecs/domain/agent/tools/schema_generator.py,sha256=
|
|
118
|
+
aiecs/domain/agent/tools/schema_generator.py,sha256=r7TP0h8qAkRAkVFygEng8Wkr5lU90WfZlgtObuHQGE0,13290
|
|
119
119
|
aiecs/domain/community/__init__.py,sha256=CcS5o6dpRM7NWm0HCl3d6MeDunwAQ1IABZlEVAQAZnU,3587
|
|
120
120
|
aiecs/domain/community/agent_adapter.py,sha256=3WeIPeOTgLEvjnv-Ee8oqL3mzh8R1r4CQfm8uqM4OA8,15139
|
|
121
121
|
aiecs/domain/community/analytics.py,sha256=CUczcN_cB7qatbeJYPVTbxb9vF9MDtZO1UkYXSrP5-o,17607
|
|
@@ -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=
|
|
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=
|
|
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=
|
|
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=
|
|
205
|
-
aiecs/llm/clients/google_function_calling_mixin.py,sha256=
|
|
206
|
-
aiecs/llm/clients/googleai_client.py,sha256
|
|
207
|
-
aiecs/llm/clients/openai_client.py,sha256=
|
|
208
|
-
aiecs/llm/clients/openai_compatible_mixin.py,sha256=
|
|
209
|
-
aiecs/llm/clients/
|
|
210
|
-
aiecs/llm/clients/
|
|
204
|
+
aiecs/llm/clients/base_client.py,sha256=X_wILA3bxftatMQ2FBAzT922-9SwaHRfBpJvCGwi-ig,13103
|
|
205
|
+
aiecs/llm/clients/google_function_calling_mixin.py,sha256=od9-kgnhKtqJc_b-M0Xi2VGAlu8QwGR5MyXt0XpoxdM,16636
|
|
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
|
|
@@ -278,10 +280,10 @@ aiecs/tools/docs/__init__.py,sha256=PBSBqnPPCbPfKF4CFc49uTcdxf36i0aBp7gNeD2166w,
|
|
|
278
280
|
aiecs/tools/docs/ai_document_orchestrator.py,sha256=i_wCs_OzzwSvZKdkP_JRkXiUGWO1levkqbRIKSGynLI,24966
|
|
279
281
|
aiecs/tools/docs/ai_document_writer_orchestrator.py,sha256=tss4kbYW378rqIET_F3XqDpl2iIZHoiP0WqW_nRx_HQ,95313
|
|
280
282
|
aiecs/tools/docs/content_insertion_tool.py,sha256=3ojzrByhFY4PhWImHWfXQ5eG5S3Z6nHMU7YgwQc9piE,48968
|
|
281
|
-
aiecs/tools/docs/document_creator_tool.py,sha256=
|
|
283
|
+
aiecs/tools/docs/document_creator_tool.py,sha256=RYsHNZopWx1KE24O-_tCjSHgUiDheS14G0_1WcDUsT0,46857
|
|
282
284
|
aiecs/tools/docs/document_layout_tool.py,sha256=FSi1REQlGyqhIkZcHpr2dwaIXuR_iZVsJk_nFwEJGDw,44761
|
|
283
|
-
aiecs/tools/docs/document_parser_tool.py,sha256=
|
|
284
|
-
aiecs/tools/docs/document_writer_tool.py,sha256=
|
|
285
|
+
aiecs/tools/docs/document_parser_tool.py,sha256=vJQzR-SE7TrWwy2YwbUEkk5lJAx9ej6Zs95qTGscix8,40688
|
|
286
|
+
aiecs/tools/docs/document_writer_tool.py,sha256=CYYBiSBRX2_fsoe1LXGPKpjWQ92Sj9o88BSSt7koRgI,78079
|
|
285
287
|
aiecs/tools/knowledge_graph/__init__.py,sha256=-UEMSWpQ6IJFPU6RkKQ4TIckf2iSbPTAVdjy2X_sWOk,430
|
|
286
288
|
aiecs/tools/knowledge_graph/graph_reasoning_tool.py,sha256=ntuF7JlCXum_Ajaa977rWR9OfXh5WgwxYIRVfZg9arg,32650
|
|
287
289
|
aiecs/tools/knowledge_graph/graph_search_tool.py,sha256=Td7LTKsobvXnSugw6o62BNsqghQuZ8OSSkKTfLLy9H0,34365
|
|
@@ -310,12 +312,12 @@ aiecs/tools/statistics/statistical_analyzer_tool.py,sha256=c62Y2RURvy6nSttS9Nvyb
|
|
|
310
312
|
aiecs/tools/task_tools/__init__.py,sha256=q9sqlTm7Acxbr8YQ5fVCREEi-8GxdENh6zAv-lKjLY8,2826
|
|
311
313
|
aiecs/tools/task_tools/chart_tool.py,sha256=FGbE6slb5nFSkdGqfJNsNsnHMSE2codo0hYfrhfX3u4,27153
|
|
312
314
|
aiecs/tools/task_tools/classfire_tool.py,sha256=FLkUUTFPlgzliVsfpS4zR1frppnIWNQj4u6hyqazdkA,32457
|
|
313
|
-
aiecs/tools/task_tools/image_tool.py,sha256=
|
|
315
|
+
aiecs/tools/task_tools/image_tool.py,sha256=UYfONlOuWkhtlaxYhTpOZV8GZ65crxw3v7aql_jiN8s,18610
|
|
314
316
|
aiecs/tools/task_tools/office_tool.py,sha256=0Nw5ppP9sXnnk65yVt9BQYy3Nil8Td33N6ue2qcUJoU,26264
|
|
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=
|
|
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.
|
|
333
|
-
aiecs-1.
|
|
334
|
-
aiecs-1.
|
|
335
|
-
aiecs-1.
|
|
336
|
-
aiecs-1.
|
|
337
|
-
aiecs-1.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|