groundx 2.4.5__tar.gz → 2.4.10__tar.gz
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 groundx might be problematic. Click here for more details.
- {groundx-2.4.5 → groundx-2.4.10}/PKG-INFO +17 -1
- {groundx-2.4.5 → groundx-2.4.10}/pyproject.toml +50 -19
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/client_wrapper.py +2 -2
- groundx-2.4.10/src/groundx/extract/__init__.py +38 -0
- groundx-2.4.10/src/groundx/extract/agents/__init__.py +7 -0
- groundx-2.4.10/src/groundx/extract/agents/agent.py +202 -0
- groundx-2.4.10/src/groundx/extract/classes/__init__.py +27 -0
- groundx-2.4.10/src/groundx/extract/classes/agent.py +22 -0
- groundx-2.4.10/src/groundx/extract/classes/api.py +15 -0
- groundx-2.4.10/src/groundx/extract/classes/document.py +311 -0
- groundx-2.4.10/src/groundx/extract/classes/field.py +88 -0
- groundx-2.4.10/src/groundx/extract/classes/groundx.py +123 -0
- groundx-2.4.10/src/groundx/extract/classes/post_process.py +33 -0
- groundx-2.4.10/src/groundx/extract/classes/prompt.py +36 -0
- groundx-2.4.10/src/groundx/extract/classes/settings.py +169 -0
- groundx-2.4.10/src/groundx/extract/classes/test_document.py +126 -0
- groundx-2.4.10/src/groundx/extract/classes/test_field.py +43 -0
- groundx-2.4.10/src/groundx/extract/classes/test_groundx.py +188 -0
- groundx-2.4.10/src/groundx/extract/classes/test_prompt.py +68 -0
- groundx-2.4.10/src/groundx/extract/classes/test_settings.py +515 -0
- groundx-2.4.10/src/groundx/extract/classes/test_utility.py +81 -0
- groundx-2.4.10/src/groundx/extract/classes/utility.py +193 -0
- groundx-2.4.10/src/groundx/extract/services/.DS_Store +0 -0
- groundx-2.4.10/src/groundx/extract/services/__init__.py +14 -0
- groundx-2.4.10/src/groundx/extract/services/csv.py +76 -0
- groundx-2.4.10/src/groundx/extract/services/logger.py +127 -0
- groundx-2.4.10/src/groundx/extract/services/logging_cfg.py +55 -0
- groundx-2.4.10/src/groundx/extract/services/ratelimit.py +104 -0
- groundx-2.4.10/src/groundx/extract/services/sheets_client.py +160 -0
- groundx-2.4.10/src/groundx/extract/services/status.py +197 -0
- groundx-2.4.10/src/groundx/extract/services/upload.py +73 -0
- groundx-2.4.10/src/groundx/extract/services/upload_minio.py +122 -0
- groundx-2.4.10/src/groundx/extract/services/upload_s3.py +84 -0
- groundx-2.4.10/src/groundx/extract/services/utility.py +52 -0
- {groundx-2.4.5 → groundx-2.4.10}/LICENSE +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/README.md +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/__init__.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/buckets/__init__.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/buckets/client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/buckets/raw_client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/__init__.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/api_error.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/datetime_utils.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/file.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/force_multipart.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/http_client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/http_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/jsonable_encoder.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/pydantic_utilities.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/query_encoder.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/remove_none_from_dict.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/request_options.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/core/serialization.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/csv_splitter.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/customer/__init__.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/customer/client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/customer/raw_client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/documents/__init__.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/documents/client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/documents/raw_client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/environment.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/errors/__init__.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/errors/bad_request_error.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/errors/unauthorized_error.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/groups/__init__.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/groups/client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/groups/raw_client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/health/__init__.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/health/client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/health/raw_client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/ingest.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/py.typed +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/search/__init__.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/search/client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/search/raw_client.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/search/types/__init__.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/search/types/search_content_request_id.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/__init__.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/bounding_box_detail.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/bucket_detail.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/bucket_list_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/bucket_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/bucket_update_detail.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/bucket_update_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/customer_detail.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/customer_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/document.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/document_detail.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/document_list_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/document_local_ingest_request.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/document_lookup_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/document_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/document_type.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/group_detail.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/group_list_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/group_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/health_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/health_response_health.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/health_service.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/health_service_status.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/ingest_local_document.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/ingest_local_document_metadata.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/ingest_remote_document.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/ingest_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/ingest_status.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/ingest_status_light.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/ingest_status_progress.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/ingest_status_progress_cancelled.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/ingest_status_progress_complete.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/ingest_status_progress_errors.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/ingest_status_progress_processing.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/message_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/meter_detail.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/process_level.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/processes_status_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/processing_status.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/search_response.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/search_response_search.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/search_result_item.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/search_result_item_pages_item.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/sort.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/sort_order.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/subscription_detail.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/subscription_detail_meters.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/types/website_source.py +0 -0
- {groundx-2.4.5 → groundx-2.4.10}/src/groundx/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: groundx
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.10
|
|
4
4
|
Summary:
|
|
5
5
|
License: MIT
|
|
6
6
|
Requires-Python: >=3.8,<4.0
|
|
@@ -22,11 +22,27 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
22
22
|
Classifier: Typing :: Typed
|
|
23
23
|
Provides-Extra: extract
|
|
24
24
|
Requires-Dist: aiohttp (>=3.8.0)
|
|
25
|
+
Requires-Dist: boto3 ; extra == "extract"
|
|
26
|
+
Requires-Dist: celery ; extra == "extract"
|
|
27
|
+
Requires-Dist: celery-types ; extra == "extract"
|
|
28
|
+
Requires-Dist: dateparser ; extra == "extract"
|
|
29
|
+
Requires-Dist: fastapi ; extra == "extract"
|
|
30
|
+
Requires-Dist: google-api-python-client ; extra == "extract"
|
|
31
|
+
Requires-Dist: google-api-python-client-stubs ; extra == "extract"
|
|
32
|
+
Requires-Dist: google-auth-stubs ; extra == "extract"
|
|
33
|
+
Requires-Dist: gspread ; extra == "extract"
|
|
25
34
|
Requires-Dist: httpx (>=0.21.2)
|
|
35
|
+
Requires-Dist: minio ; extra == "extract"
|
|
36
|
+
Requires-Dist: pandas ; extra == "extract"
|
|
37
|
+
Requires-Dist: pandas-stubs ; extra == "extract"
|
|
38
|
+
Requires-Dist: pillow ; extra == "extract"
|
|
26
39
|
Requires-Dist: pydantic (>=1.9.2)
|
|
27
40
|
Requires-Dist: pydantic-core (>=2.18.2,<3.0.0)
|
|
41
|
+
Requires-Dist: redis ; extra == "extract"
|
|
28
42
|
Requires-Dist: requests (>=2.4.0)
|
|
29
43
|
Requires-Dist: tqdm (>=4.60.0)
|
|
44
|
+
Requires-Dist: types-boto3 ; extra == "extract"
|
|
45
|
+
Requires-Dist: types-dateparser ; extra == "extract"
|
|
30
46
|
Requires-Dist: types-tqdm (>=4.60.0)
|
|
31
47
|
Requires-Dist: typing_extensions (>=4.0.0)
|
|
32
48
|
Description-Content-Type: text/markdown
|
|
@@ -3,7 +3,7 @@ name = "groundx"
|
|
|
3
3
|
|
|
4
4
|
[tool.poetry]
|
|
5
5
|
name = "groundx"
|
|
6
|
-
version = "2.4.
|
|
6
|
+
version = "2.4.10"
|
|
7
7
|
description = ""
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
authors = []
|
|
@@ -37,11 +37,27 @@ Repository = 'https://github.com/eyelevelai/groundx-python'
|
|
|
37
37
|
[tool.poetry.dependencies]
|
|
38
38
|
python = "^3.8"
|
|
39
39
|
aiohttp = ">=3.8.0"
|
|
40
|
+
boto3 = { version = "*", optional = true}
|
|
41
|
+
celery = { version = "*", optional = true}
|
|
42
|
+
celery-types = { version = "*", optional = true}
|
|
43
|
+
dateparser = { version = "*", optional = true}
|
|
44
|
+
fastapi = { version = "*", optional = true}
|
|
45
|
+
google-api-python-client = { version = "*", optional = true}
|
|
46
|
+
google-api-python-client-stubs = { version = "*", optional = true}
|
|
47
|
+
google-auth-stubs = { version = "*", optional = true}
|
|
48
|
+
gspread = { version = "*", optional = true}
|
|
40
49
|
httpx = ">=0.21.2"
|
|
50
|
+
minio = { version = "*", optional = true}
|
|
51
|
+
pandas = { version = "*", optional = true}
|
|
52
|
+
pandas-stubs = { version = "*", optional = true}
|
|
53
|
+
pillow = { version = "*", optional = true}
|
|
41
54
|
pydantic = ">= 1.9.2"
|
|
42
55
|
pydantic-core = "^2.18.2"
|
|
56
|
+
redis = { version = "*", optional = true}
|
|
43
57
|
requests = ">=2.4.0"
|
|
44
58
|
tqdm = ">=4.60.0"
|
|
59
|
+
types-boto3 = { version = "*", optional = true}
|
|
60
|
+
types-dateparser = { version = "*", optional = true}
|
|
45
61
|
types-tqdm = ">=4.60.0"
|
|
46
62
|
typing_extensions = ">= 4.0.0"
|
|
47
63
|
|
|
@@ -89,22 +105,37 @@ section-order = ["future", "standard-library", "third-party", "first-party"]
|
|
|
89
105
|
requires = ["poetry-core"]
|
|
90
106
|
build-backend = "poetry.core.masonry.api"
|
|
91
107
|
|
|
92
|
-
tool.poetry.dependencies.celery = { version = "*", optional = true, extras = ["redis"] }
|
|
93
|
-
tool.poetry.dependencies.celery-types = { version = "*", optional = true }
|
|
94
|
-
tool.poetry.dependencies.fastapi = { version = "*", optional = true }
|
|
95
|
-
tool.poetry.dependencies.google-api-python-client = { version = "*", optional = true }
|
|
96
|
-
tool.poetry.dependencies.google-api-python-client-stubs = { version = "*", optional = true }
|
|
97
|
-
tool.poetry.dependencies.google-auth-stubs = { version = "*", optional = true }
|
|
98
|
-
tool.poetry.dependencies.gspread = { version = "*", optional = true }
|
|
99
|
-
tool.poetry.dependencies.boto3 = { version = "*", optional = true }
|
|
100
|
-
tool.poetry.dependencies.types-boto3 = { version = "*", optional = true }
|
|
101
|
-
tool.poetry.dependencies.dateparser = { version = "*", optional = true }
|
|
102
|
-
tool.poetry.dependencies.minio = { version = "*", optional = true }
|
|
103
|
-
tool.poetry.dependencies.pandas = { version = "*", optional = true }
|
|
104
|
-
tool.poetry.dependencies.pandas-stubs = { version = "*", optional = true }
|
|
105
|
-
tool.poetry.dependencies.redis = { version = "*", optional = true }
|
|
106
|
-
tool.poetry.dependencies.smolagents = { version = ">=1.19.0", optional = true, extras = ["openai"] }
|
|
107
|
-
tool.poetry.dependencies.pillow = { version = "*", optional = true }
|
|
108
|
-
|
|
109
108
|
[tool.poetry.extras]
|
|
110
|
-
extract=["celery", "celery-types", "fastapi", "google-api-python-client", "google-api-python-client-stubs", "google-auth-stubs", "gspread", "boto3", "types-boto3", "dateparser", "minio", "pandas", "pandas-stubs", "redis", "
|
|
109
|
+
extract=["celery", "celery-types", "fastapi", "google-api-python-client", "google-api-python-client-stubs", "google-auth-stubs", "gspread", "boto3", "types-boto3", "dateparser", "types-dateparser", "minio", "pandas", "pandas-stubs", "redis", "pillow"]
|
|
110
|
+
|
|
111
|
+
[[tool.mypy.overrides]]
|
|
112
|
+
module = ["PIL.*"]
|
|
113
|
+
ignore_missing_imports = true
|
|
114
|
+
|
|
115
|
+
[[tool.mypy.overrides]]
|
|
116
|
+
module = ["boto3.*", "botocore.*"]
|
|
117
|
+
ignore_missing_imports = true
|
|
118
|
+
|
|
119
|
+
[[tool.mypy.overrides]]
|
|
120
|
+
module = ["minio.*"]
|
|
121
|
+
ignore_missing_imports = true
|
|
122
|
+
|
|
123
|
+
[[tool.mypy.overrides]]
|
|
124
|
+
module = ["google.*", "googleapiclient.*", "gspread.*"]
|
|
125
|
+
ignore_missing_imports = true
|
|
126
|
+
|
|
127
|
+
[[tool.mypy.overrides]]
|
|
128
|
+
module = ["fastapi.*", "starlette.*", "redis.*"]
|
|
129
|
+
ignore_missing_imports = true
|
|
130
|
+
|
|
131
|
+
[[tool.mypy.overrides]]
|
|
132
|
+
module = ["smolagents.*"]
|
|
133
|
+
ignore_missing_imports = true
|
|
134
|
+
|
|
135
|
+
[[tool.mypy.overrides]]
|
|
136
|
+
module = ["dateparser.*"]
|
|
137
|
+
ignore_missing_imports = true
|
|
138
|
+
|
|
139
|
+
[[tool.mypy.overrides]]
|
|
140
|
+
module = ["groundx.extract.classes.document"]
|
|
141
|
+
disable_error_code = ["call-arg"]
|
|
@@ -14,10 +14,10 @@ class BaseClientWrapper:
|
|
|
14
14
|
|
|
15
15
|
def get_headers(self) -> typing.Dict[str, str]:
|
|
16
16
|
headers: typing.Dict[str, str] = {
|
|
17
|
-
"User-Agent": "groundx/2.4.
|
|
17
|
+
"User-Agent": "groundx/2.4.10",
|
|
18
18
|
"X-Fern-Language": "Python",
|
|
19
19
|
"X-Fern-SDK-Name": "groundx",
|
|
20
|
-
"X-Fern-SDK-Version": "2.4.
|
|
20
|
+
"X-Fern-SDK-Version": "2.4.10",
|
|
21
21
|
}
|
|
22
22
|
headers["X-API-Key"] = self.api_key
|
|
23
23
|
return headers
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from .agents import AgentCode, AgentTool
|
|
2
|
+
from .classes import (
|
|
3
|
+
AgentRequest,
|
|
4
|
+
AgentSettings,
|
|
5
|
+
ContainerSettings,
|
|
6
|
+
ContainerUploadSettings,
|
|
7
|
+
Document,
|
|
8
|
+
DocumentRequest,
|
|
9
|
+
ExtractedField,
|
|
10
|
+
GroundXDocument,
|
|
11
|
+
GroundXSettings,
|
|
12
|
+
ProcessResponse,
|
|
13
|
+
Prompt,
|
|
14
|
+
XRayDocument,
|
|
15
|
+
)
|
|
16
|
+
from .services import Logger, RateLimit, SheetsClient, Status, Upload
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"AgentCode",
|
|
20
|
+
"AgentRequest",
|
|
21
|
+
"AgentSettings",
|
|
22
|
+
"AgentTool",
|
|
23
|
+
"ContainerSettings",
|
|
24
|
+
"ContainerUploadSettings",
|
|
25
|
+
"Document",
|
|
26
|
+
"DocumentRequest",
|
|
27
|
+
"ExtractedField",
|
|
28
|
+
"GroundXDocument",
|
|
29
|
+
"GroundXSettings",
|
|
30
|
+
"Logger",
|
|
31
|
+
"ProcessResponse",
|
|
32
|
+
"Prompt",
|
|
33
|
+
"RateLimit",
|
|
34
|
+
"SheetsClient",
|
|
35
|
+
"Status",
|
|
36
|
+
"Upload",
|
|
37
|
+
"XRayDocument",
|
|
38
|
+
]
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import json, pytest, traceback, typing
|
|
2
|
+
|
|
3
|
+
pytest.importorskip("PIL")
|
|
4
|
+
|
|
5
|
+
from PIL.Image import Image
|
|
6
|
+
|
|
7
|
+
from smolagents import ( # pyright: ignore[reportMissingTypeStubs]
|
|
8
|
+
CodeAgent,
|
|
9
|
+
Tool,
|
|
10
|
+
ToolCallingAgent,
|
|
11
|
+
)
|
|
12
|
+
from smolagents.models import ( # pyright: ignore[reportMissingTypeStubs]
|
|
13
|
+
OpenAIServerModel,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from ..classes.settings import AgentSettings
|
|
17
|
+
from ..classes.utility import clean_json
|
|
18
|
+
from ..services.logger import Logger
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
prompt_suffix = """
|
|
22
|
+
Return only your response using the `final_answer` tool format:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{{"answer": {{"type": RESPONSE_HERE, "description": "The final answer to the problem"}}}}
|
|
26
|
+
```
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def extract_response(res: typing.Dict[str, typing.Any]) -> typing.Any:
|
|
31
|
+
if "answer" in res and "type" in res["answer"]:
|
|
32
|
+
return res["answer"]["type"]
|
|
33
|
+
|
|
34
|
+
if "type" in res:
|
|
35
|
+
return res["type"]
|
|
36
|
+
|
|
37
|
+
return res
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def process_response(
|
|
41
|
+
res: typing.Any,
|
|
42
|
+
expected_types: typing.Union[type, typing.Tuple[type, ...]] = dict,
|
|
43
|
+
) -> typing.Any:
|
|
44
|
+
if not isinstance(res, expected_types):
|
|
45
|
+
if (
|
|
46
|
+
isinstance(res, list)
|
|
47
|
+
and isinstance(dict(), expected_types)
|
|
48
|
+
and len(res) == 1 # pyright: ignore[reportUnknownArgumentType]
|
|
49
|
+
):
|
|
50
|
+
return extract_response(
|
|
51
|
+
res[0] # pyright: ignore[reportUnknownArgumentType]
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
if not isinstance(res, str):
|
|
55
|
+
traceback.print_stack()
|
|
56
|
+
raise TypeError(
|
|
57
|
+
f"agent process result is not of expected type(s) {expected_types!r}, got {type(res)!r}" # type: ignore
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
res = clean_json(res)
|
|
61
|
+
|
|
62
|
+
loaded = json.loads(res)
|
|
63
|
+
if not isinstance(loaded, expected_types):
|
|
64
|
+
if isinstance(loaded, list) and isinstance(dict(), expected_types) and len(loaded) == 1: # type: ignore
|
|
65
|
+
return extract_response(loaded[0]) # type: ignore
|
|
66
|
+
|
|
67
|
+
traceback.print_stack()
|
|
68
|
+
raise TypeError(
|
|
69
|
+
f"agent process result is not of expected type(s) {expected_types!r} after JSON parsing, got {type(loaded)!r}" # type: ignore
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
if isinstance(loaded, typing.Dict):
|
|
73
|
+
return extract_response(loaded) # type: ignore
|
|
74
|
+
|
|
75
|
+
return loaded
|
|
76
|
+
|
|
77
|
+
if isinstance(res, typing.Dict):
|
|
78
|
+
return extract_response(res) # type: ignore
|
|
79
|
+
|
|
80
|
+
return res
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class AgentCode(CodeAgent):
|
|
84
|
+
def __init__(
|
|
85
|
+
self,
|
|
86
|
+
settings: AgentSettings,
|
|
87
|
+
logger: Logger,
|
|
88
|
+
name: typing.Optional[str] = None,
|
|
89
|
+
description: typing.Optional[str] = None,
|
|
90
|
+
tools: typing.Optional[typing.List[Tool]] = None,
|
|
91
|
+
verbosity: typing.Optional[int] = 0,
|
|
92
|
+
):
|
|
93
|
+
if tools is None:
|
|
94
|
+
tools = []
|
|
95
|
+
|
|
96
|
+
model = OpenAIServerModel(
|
|
97
|
+
model_id=settings.model_id,
|
|
98
|
+
api_base=settings.api_base,
|
|
99
|
+
api_key=settings.get_api_key(),
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
super().__init__( # pyright: ignore[reportUnknownMemberType]
|
|
103
|
+
name=name,
|
|
104
|
+
description=description,
|
|
105
|
+
additional_authorized_imports=settings.imports,
|
|
106
|
+
tools=tools,
|
|
107
|
+
model=model,
|
|
108
|
+
max_steps=settings.max_steps,
|
|
109
|
+
verbosity_level=verbosity,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
if self.python_executor.static_tools is None: # type: ignore
|
|
113
|
+
self.python_executor.static_tools = {} # type: ignore
|
|
114
|
+
|
|
115
|
+
self.python_executor.static_tools.update({"open": open}) # type: ignore
|
|
116
|
+
|
|
117
|
+
self.logger = logger
|
|
118
|
+
|
|
119
|
+
def process(
|
|
120
|
+
self,
|
|
121
|
+
conflict: str,
|
|
122
|
+
images: typing.List[Image],
|
|
123
|
+
expected_types: typing.Union[type, typing.Tuple[type, ...]] = dict,
|
|
124
|
+
attempt: int = 0,
|
|
125
|
+
) -> typing.Any:
|
|
126
|
+
res = super().run( # pyright: ignore[reportUnknownMemberType]
|
|
127
|
+
conflict + prompt_suffix,
|
|
128
|
+
images=images,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
try:
|
|
132
|
+
return process_response(res=res, expected_types=expected_types)
|
|
133
|
+
|
|
134
|
+
except Exception as e:
|
|
135
|
+
if attempt > 2:
|
|
136
|
+
raise TypeError(
|
|
137
|
+
f"agent process result is not of expected type(s) {expected_types!r}: [{e}]\n\n{res}"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
self.logger.debug_msg(
|
|
141
|
+
f"agent process result is not of expected type(s) {expected_types!r}: [{e}], attempting again [{attempt+1}]\n\n{res}"
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
return self.process(conflict, images, expected_types, attempt + 1)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class AgentTool(ToolCallingAgent):
|
|
148
|
+
def __init__(
|
|
149
|
+
self,
|
|
150
|
+
settings: AgentSettings,
|
|
151
|
+
logger: Logger,
|
|
152
|
+
name: typing.Optional[str] = None,
|
|
153
|
+
description: typing.Optional[str] = None,
|
|
154
|
+
tools: typing.Optional[typing.List[Tool]] = None,
|
|
155
|
+
verbosity: typing.Optional[int] = 0,
|
|
156
|
+
):
|
|
157
|
+
if tools is None:
|
|
158
|
+
tools = []
|
|
159
|
+
|
|
160
|
+
model = OpenAIServerModel(
|
|
161
|
+
model_id=settings.model_id,
|
|
162
|
+
api_base=settings.api_base,
|
|
163
|
+
api_key=settings.get_api_key(),
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
super().__init__( # pyright: ignore[reportUnknownMemberType]
|
|
167
|
+
name=name,
|
|
168
|
+
description=description,
|
|
169
|
+
tools=tools,
|
|
170
|
+
model=model,
|
|
171
|
+
max_steps=settings.max_steps,
|
|
172
|
+
verbosity_level=verbosity,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
self.logger = logger
|
|
176
|
+
|
|
177
|
+
def process(
|
|
178
|
+
self,
|
|
179
|
+
conflict: str,
|
|
180
|
+
images: typing.List[Image],
|
|
181
|
+
expected_types: typing.Union[type, typing.Tuple[type, ...]] = dict,
|
|
182
|
+
attempt: int = 0,
|
|
183
|
+
) -> typing.Any:
|
|
184
|
+
res = super().run( # pyright: ignore[reportUnknownMemberType]
|
|
185
|
+
conflict + prompt_suffix,
|
|
186
|
+
images=images,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
try:
|
|
190
|
+
return process_response(res=res, expected_types=expected_types)
|
|
191
|
+
|
|
192
|
+
except Exception as e:
|
|
193
|
+
if attempt > 2:
|
|
194
|
+
raise TypeError(
|
|
195
|
+
f"agent process result is not of expected type(s) {expected_types!r}: [{e}]\n\n{res}"
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
print(
|
|
199
|
+
f"agent process result is not of expected type(s) {expected_types!r}: [{e}], attempting again [{attempt+1}]\n\n{res}"
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
return self.process(conflict, images, expected_types, attempt + 1)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from .agent import AgentRequest
|
|
2
|
+
from .api import ProcessResponse
|
|
3
|
+
from .document import Document, DocumentRequest
|
|
4
|
+
from .field import ExtractedField
|
|
5
|
+
from .groundx import GroundXDocument, XRayDocument
|
|
6
|
+
from .prompt import Prompt
|
|
7
|
+
from .settings import (
|
|
8
|
+
AgentSettings,
|
|
9
|
+
ContainerSettings,
|
|
10
|
+
ContainerUploadSettings,
|
|
11
|
+
GroundXSettings,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"AgentRequest",
|
|
16
|
+
"AgentSettings",
|
|
17
|
+
"ContainerSettings",
|
|
18
|
+
"ContainerUploadSettings",
|
|
19
|
+
"Document",
|
|
20
|
+
"DocumentRequest",
|
|
21
|
+
"ExtractedField",
|
|
22
|
+
"GroundXDocument",
|
|
23
|
+
"GroundXSettings",
|
|
24
|
+
"ProcessResponse",
|
|
25
|
+
"Prompt",
|
|
26
|
+
"XRayDocument",
|
|
27
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
from pydantic import BaseModel, field_validator
|
|
3
|
+
|
|
4
|
+
from .document import Document, DocumentRequest
|
|
5
|
+
|
|
6
|
+
ReqT = typing.TypeVar("ReqT", bound=DocumentRequest)
|
|
7
|
+
DocT = typing.TypeVar("DocT", bound=Document)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AgentRequest(BaseModel, typing.Generic[ReqT, DocT]):
|
|
11
|
+
allowed_request_types: typing.List[str] = []
|
|
12
|
+
request: ReqT
|
|
13
|
+
request_type: str
|
|
14
|
+
statement: DocT
|
|
15
|
+
|
|
16
|
+
@field_validator("request_type")
|
|
17
|
+
def validate_request_type(cls, value: str):
|
|
18
|
+
if value not in cls.allowed_request_types:
|
|
19
|
+
raise ValueError(
|
|
20
|
+
f"Invalid request_type '{value}'. Must be one of {cls.allowed_request_types}"
|
|
21
|
+
)
|
|
22
|
+
return value
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ErrorResponse(BaseModel):
|
|
6
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
7
|
+
code: int
|
|
8
|
+
document_id: str = Field(alias="documentID")
|
|
9
|
+
message: str
|
|
10
|
+
task_id: str = Field(alias="taskID")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class ProcessResponse:
|
|
15
|
+
message: str
|