weni-utils-tools 0.0.1__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.
- weni_utils_tools-0.0.1/CHANGELOG.md +26 -0
- weni_utils_tools-0.0.1/LICENSE +21 -0
- weni_utils_tools-0.0.1/MANIFEST.in +26 -0
- weni_utils_tools-0.0.1/PKG-INFO +265 -0
- weni_utils_tools-0.0.1/README.md +217 -0
- weni_utils_tools-0.0.1/pyproject.toml +125 -0
- weni_utils_tools-0.0.1/setup.cfg +4 -0
- weni_utils_tools-0.0.1/src/weni_utils/__init__.py +7 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/__init__.py +67 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/client.py +610 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/concierge.py +440 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/context.py +66 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/functions.py +325 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/orders.py +142 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/plugins/__init__.py +60 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/plugins/base.py +136 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/plugins/capi.py +190 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/plugins/carousel.py +326 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/plugins/cart_simulation.py +214 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/plugins/regionalization.py +177 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/plugins/send_message.py +440 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/plugins/utils.py +359 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/plugins/weni_flow.py +147 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/plugins/wholesale.py +140 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/py.typed +2 -0
- weni_utils_tools-0.0.1/src/weni_utils/tools/stock.py +295 -0
- weni_utils_tools-0.0.1/src/weni_utils_tools.egg-info/PKG-INFO +265 -0
- weni_utils_tools-0.0.1/src/weni_utils_tools.egg-info/SOURCES.txt +33 -0
- weni_utils_tools-0.0.1/src/weni_utils_tools.egg-info/dependency_links.txt +1 -0
- weni_utils_tools-0.0.1/src/weni_utils_tools.egg-info/requires.txt +18 -0
- weni_utils_tools-0.0.1/src/weni_utils_tools.egg-info/top_level.txt +1 -0
- weni_utils_tools-0.0.1/tests/__init__.py +1 -0
- weni_utils_tools-0.0.1/tests/test_client.py +173 -0
- weni_utils_tools-0.0.1/tests/test_concierge.py +158 -0
- weni_utils_tools-0.0.1/tests/test_orders.py +69 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.0.1] - 2026-02-01
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release of weni-utils-tools
|
|
12
|
+
- `ProductConcierge` - Main class for product search orchestration
|
|
13
|
+
- `VTEXClient` - VTEX API client with intelligent search, cart simulation, and regionalization
|
|
14
|
+
- `StockManager` - Stock availability verification and filtering
|
|
15
|
+
- `SearchContext` - Shared context for plugin communication
|
|
16
|
+
|
|
17
|
+
### Plugins
|
|
18
|
+
- `Regionalization` - Postal code-based region and seller selection
|
|
19
|
+
- `Wholesale` - Wholesale pricing (minQuantity, valueAtacado)
|
|
20
|
+
- `Carousel` - WhatsApp carousel message formatting and sending
|
|
21
|
+
- `CAPI` - Meta Conversions API integration
|
|
22
|
+
- `WeniFlowTrigger` - Weni flow triggering
|
|
23
|
+
|
|
24
|
+
### Documentation
|
|
25
|
+
- Complete README with usage examples
|
|
26
|
+
- Example implementations for agents
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Weni AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Include essential files
|
|
2
|
+
include LICENSE
|
|
3
|
+
include README.md
|
|
4
|
+
include CHANGELOG.md
|
|
5
|
+
include py.typed
|
|
6
|
+
|
|
7
|
+
# Include source files
|
|
8
|
+
recursive-include src *.py
|
|
9
|
+
recursive-include src *.pyi
|
|
10
|
+
|
|
11
|
+
# Include tests
|
|
12
|
+
recursive-include tests *.py
|
|
13
|
+
|
|
14
|
+
# Exclude compiled files
|
|
15
|
+
global-exclude *.py[cod]
|
|
16
|
+
global-exclude __pycache__
|
|
17
|
+
global-exclude *.so
|
|
18
|
+
global-exclude .DS_Store
|
|
19
|
+
|
|
20
|
+
# Exclude development files
|
|
21
|
+
exclude .gitignore
|
|
22
|
+
exclude .pre-commit-config.yaml
|
|
23
|
+
prune .github
|
|
24
|
+
prune .git
|
|
25
|
+
prune examples
|
|
26
|
+
prune docs
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: weni-utils-tools
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Modular tools library for AI agents on the Weni platform
|
|
5
|
+
Author-email: Weni AI <dev@weni.ai>
|
|
6
|
+
Maintainer-email: Weni AI <dev@weni.ai>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/weni-ai/tools-utils
|
|
9
|
+
Project-URL: Documentation, https://github.com/weni-ai/tools-utils#readme
|
|
10
|
+
Project-URL: Repository, https://github.com/weni-ai/tools-utils.git
|
|
11
|
+
Project-URL: Issues, https://github.com/weni-ai/tools-utils/issues
|
|
12
|
+
Project-URL: Changelog, https://github.com/weni-ai/tools-utils/blob/main/CHANGELOG.md
|
|
13
|
+
Keywords: weni,vtex,ecommerce,ai-agent,chatbot,whatsapp,product-search,intelligent-search,tools
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
26
|
+
Classifier: Topic :: Communications :: Chat
|
|
27
|
+
Classifier: Typing :: Typed
|
|
28
|
+
Requires-Python: >=3.9
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: requests<3.0.0,>=2.28.0
|
|
32
|
+
Requires-Dist: pytz>=2023.3
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
|
|
37
|
+
Requires-Dist: responses>=0.23.0; extra == "dev"
|
|
38
|
+
Requires-Dist: black==24.10.0; extra == "dev"
|
|
39
|
+
Requires-Dist: isort==5.13.2; extra == "dev"
|
|
40
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
41
|
+
Requires-Dist: types-requests>=2.28.0; extra == "dev"
|
|
42
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
43
|
+
Provides-Extra: docs
|
|
44
|
+
Requires-Dist: sphinx>=6.0.0; extra == "docs"
|
|
45
|
+
Requires-Dist: sphinx-rtd-theme>=1.2.0; extra == "docs"
|
|
46
|
+
Requires-Dist: myst-parser>=1.0.0; extra == "docs"
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
|
|
49
|
+
# Weni Tools
|
|
50
|
+
|
|
51
|
+
Modular tools library for AI agents on the Weni platform.
|
|
52
|
+
|
|
53
|
+
## 📦 Installation
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install weni-utils-tools
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
> **Note**: The package name on PyPI is `weni-utils-tools` (with hyphens), and you import it as `weni_utils.tools`:
|
|
60
|
+
> - Install: `pip install weni-utils-tools`
|
|
61
|
+
> - Import: `from weni_utils.tools import ...`
|
|
62
|
+
|
|
63
|
+
## 🎯 Problem Solved
|
|
64
|
+
|
|
65
|
+
Before this library, each client had a complete copy of the agent code, resulting in:
|
|
66
|
+
- ❌ Duplicated code (70%+ identical between clients)
|
|
67
|
+
- ❌ Bug fix = N manual deploys
|
|
68
|
+
- ❌ Exponential maintenance
|
|
69
|
+
- ❌ Difficult onboarding of new clients
|
|
70
|
+
|
|
71
|
+
## ✅ Solution
|
|
72
|
+
|
|
73
|
+
A centralized library with plugin system:
|
|
74
|
+
- ✅ Shared core (search, simulation, stock)
|
|
75
|
+
- ✅ Optional plugins (regionalization, wholesale, carousel)
|
|
76
|
+
- ✅ Bug fix = 1 deploy, all updated
|
|
77
|
+
- ✅ New client = import and configure plugins
|
|
78
|
+
|
|
79
|
+
## 🚀 Basic Usage
|
|
80
|
+
|
|
81
|
+
### Modular Functions (Recommended)
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from weni_utils.tools import search_products, get_region, simulate_cart
|
|
85
|
+
|
|
86
|
+
# Search products
|
|
87
|
+
products = search_products(
|
|
88
|
+
base_url="https://store.vtexcommercestable.com.br",
|
|
89
|
+
product_name="drill",
|
|
90
|
+
max_products=10
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Get region by postal code
|
|
94
|
+
region_id, error, sellers = get_region(
|
|
95
|
+
base_url="https://store.vtexcommercestable.com.br",
|
|
96
|
+
postal_code="01310-100"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# Simulate cart
|
|
100
|
+
result = simulate_cart(
|
|
101
|
+
base_url="https://store.vtexcommercestable.com.br",
|
|
102
|
+
items=[{"id": "61556", "quantity": 1, "seller": "1"}],
|
|
103
|
+
postal_code="01310-100"
|
|
104
|
+
)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Orchestration Class
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from weni_utils.tools import ProductConcierge
|
|
111
|
+
|
|
112
|
+
concierge = ProductConcierge(
|
|
113
|
+
base_url="https://store.vtexcommercestable.com.br",
|
|
114
|
+
store_url="https://store.com.br"
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
result = concierge.search(product_name="drill")
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## 🔌 Available Plugins
|
|
121
|
+
|
|
122
|
+
### Regionalization
|
|
123
|
+
For clients with postal code-based regionalization.
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from weni_utils.tools import ProductConcierge
|
|
127
|
+
from weni_utils.tools.plugins import Regionalization
|
|
128
|
+
|
|
129
|
+
concierge = ProductConcierge(
|
|
130
|
+
base_url="...",
|
|
131
|
+
store_url="...",
|
|
132
|
+
plugins=[
|
|
133
|
+
Regionalization()
|
|
134
|
+
]
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
result = concierge.search(
|
|
138
|
+
product_name="cement",
|
|
139
|
+
postal_code="01310-100"
|
|
140
|
+
)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Wholesale
|
|
144
|
+
For clients with wholesale pricing.
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from weni_utils.tools.plugins import Wholesale
|
|
148
|
+
|
|
149
|
+
concierge = ProductConcierge(
|
|
150
|
+
plugins=[
|
|
151
|
+
Wholesale(fixed_price_url="https://store.com.br/fixedprices")
|
|
152
|
+
]
|
|
153
|
+
)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Carousel
|
|
157
|
+
For sending products via WhatsApp carousel.
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from weni_utils.tools.plugins import Carousel
|
|
161
|
+
|
|
162
|
+
concierge = ProductConcierge(
|
|
163
|
+
plugins=[
|
|
164
|
+
Carousel(
|
|
165
|
+
weni_token="your-token",
|
|
166
|
+
max_items=10,
|
|
167
|
+
auto_send=True
|
|
168
|
+
)
|
|
169
|
+
]
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
result = concierge.search(
|
|
173
|
+
product_name="shirt",
|
|
174
|
+
contact_info={"urn": "whatsapp:5511999999999"}
|
|
175
|
+
)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### CAPI (Meta Conversions API)
|
|
179
|
+
For sending conversion events to Meta.
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from weni_utils.tools.plugins import CAPI
|
|
183
|
+
|
|
184
|
+
concierge = ProductConcierge(
|
|
185
|
+
plugins=[
|
|
186
|
+
CAPI(event_type="lead", auto_send=True)
|
|
187
|
+
]
|
|
188
|
+
)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### WeniFlowTrigger
|
|
192
|
+
For triggering Weni flows.
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
from weni_utils.tools.plugins import WeniFlowTrigger
|
|
196
|
+
|
|
197
|
+
concierge = ProductConcierge(
|
|
198
|
+
plugins=[
|
|
199
|
+
WeniFlowTrigger(
|
|
200
|
+
flow_uuid="flow-uuid",
|
|
201
|
+
trigger_once=True
|
|
202
|
+
)
|
|
203
|
+
]
|
|
204
|
+
)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## 🏗️ Architecture
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
211
|
+
│ ProductConcierge │
|
|
212
|
+
│ (Orchestrates entire flow) │
|
|
213
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
214
|
+
│
|
|
215
|
+
┌────────────────────┼────────────────────┐
|
|
216
|
+
│ │ │
|
|
217
|
+
▼ ▼ ▼
|
|
218
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
219
|
+
│ VTEXClient │ │ StockManager │ │ Plugins │
|
|
220
|
+
│ │ │ │ │ │
|
|
221
|
+
│ • search() │ │ • check() │ │ • before_search │
|
|
222
|
+
│ • simulate() │ │ • filter() │ │ • after_search │
|
|
223
|
+
│ • get_region() │ │ • limit_size() │ │ • enrich() │
|
|
224
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## 🔄 Execution Flow
|
|
228
|
+
|
|
229
|
+
1. **before_search** - Plugins modify context (e.g., get region_id)
|
|
230
|
+
2. **intelligent_search** - Search products in VTEX
|
|
231
|
+
3. **after_search** - Plugins filter/modify products
|
|
232
|
+
4. **check_availability** - Verify stock
|
|
233
|
+
5. **after_stock_check** - Plugins enrich (e.g., wholesale prices)
|
|
234
|
+
6. **filter_products** - Filter only products with stock
|
|
235
|
+
7. **enrich_products** - Plugins add extra data
|
|
236
|
+
8. **finalize_result** - Plugins perform final actions (e.g., send events)
|
|
237
|
+
|
|
238
|
+
## 🤝 Creating a New Plugin
|
|
239
|
+
|
|
240
|
+
```python
|
|
241
|
+
from weni_utils.tools.plugins import PluginBase
|
|
242
|
+
|
|
243
|
+
class MyPlugin(PluginBase):
|
|
244
|
+
name = "my_plugin"
|
|
245
|
+
|
|
246
|
+
def before_search(self, context, client):
|
|
247
|
+
# Modify context before search
|
|
248
|
+
return context
|
|
249
|
+
|
|
250
|
+
def after_search(self, products, context, client):
|
|
251
|
+
# Modify products after search
|
|
252
|
+
return products
|
|
253
|
+
|
|
254
|
+
def after_stock_check(self, products_with_stock, context, client):
|
|
255
|
+
# Enrich products after stock check
|
|
256
|
+
return products_with_stock
|
|
257
|
+
|
|
258
|
+
def finalize_result(self, result, context):
|
|
259
|
+
# Final modification before return
|
|
260
|
+
return result
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## 📝 License
|
|
264
|
+
|
|
265
|
+
MIT License - Weni AI
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# Weni Tools
|
|
2
|
+
|
|
3
|
+
Modular tools library for AI agents on the Weni platform.
|
|
4
|
+
|
|
5
|
+
## 📦 Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install weni-utils-tools
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
> **Note**: The package name on PyPI is `weni-utils-tools` (with hyphens), and you import it as `weni_utils.tools`:
|
|
12
|
+
> - Install: `pip install weni-utils-tools`
|
|
13
|
+
> - Import: `from weni_utils.tools import ...`
|
|
14
|
+
|
|
15
|
+
## 🎯 Problem Solved
|
|
16
|
+
|
|
17
|
+
Before this library, each client had a complete copy of the agent code, resulting in:
|
|
18
|
+
- ❌ Duplicated code (70%+ identical between clients)
|
|
19
|
+
- ❌ Bug fix = N manual deploys
|
|
20
|
+
- ❌ Exponential maintenance
|
|
21
|
+
- ❌ Difficult onboarding of new clients
|
|
22
|
+
|
|
23
|
+
## ✅ Solution
|
|
24
|
+
|
|
25
|
+
A centralized library with plugin system:
|
|
26
|
+
- ✅ Shared core (search, simulation, stock)
|
|
27
|
+
- ✅ Optional plugins (regionalization, wholesale, carousel)
|
|
28
|
+
- ✅ Bug fix = 1 deploy, all updated
|
|
29
|
+
- ✅ New client = import and configure plugins
|
|
30
|
+
|
|
31
|
+
## 🚀 Basic Usage
|
|
32
|
+
|
|
33
|
+
### Modular Functions (Recommended)
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from weni_utils.tools import search_products, get_region, simulate_cart
|
|
37
|
+
|
|
38
|
+
# Search products
|
|
39
|
+
products = search_products(
|
|
40
|
+
base_url="https://store.vtexcommercestable.com.br",
|
|
41
|
+
product_name="drill",
|
|
42
|
+
max_products=10
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Get region by postal code
|
|
46
|
+
region_id, error, sellers = get_region(
|
|
47
|
+
base_url="https://store.vtexcommercestable.com.br",
|
|
48
|
+
postal_code="01310-100"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Simulate cart
|
|
52
|
+
result = simulate_cart(
|
|
53
|
+
base_url="https://store.vtexcommercestable.com.br",
|
|
54
|
+
items=[{"id": "61556", "quantity": 1, "seller": "1"}],
|
|
55
|
+
postal_code="01310-100"
|
|
56
|
+
)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Orchestration Class
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from weni_utils.tools import ProductConcierge
|
|
63
|
+
|
|
64
|
+
concierge = ProductConcierge(
|
|
65
|
+
base_url="https://store.vtexcommercestable.com.br",
|
|
66
|
+
store_url="https://store.com.br"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
result = concierge.search(product_name="drill")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## 🔌 Available Plugins
|
|
73
|
+
|
|
74
|
+
### Regionalization
|
|
75
|
+
For clients with postal code-based regionalization.
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from weni_utils.tools import ProductConcierge
|
|
79
|
+
from weni_utils.tools.plugins import Regionalization
|
|
80
|
+
|
|
81
|
+
concierge = ProductConcierge(
|
|
82
|
+
base_url="...",
|
|
83
|
+
store_url="...",
|
|
84
|
+
plugins=[
|
|
85
|
+
Regionalization()
|
|
86
|
+
]
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
result = concierge.search(
|
|
90
|
+
product_name="cement",
|
|
91
|
+
postal_code="01310-100"
|
|
92
|
+
)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Wholesale
|
|
96
|
+
For clients with wholesale pricing.
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from weni_utils.tools.plugins import Wholesale
|
|
100
|
+
|
|
101
|
+
concierge = ProductConcierge(
|
|
102
|
+
plugins=[
|
|
103
|
+
Wholesale(fixed_price_url="https://store.com.br/fixedprices")
|
|
104
|
+
]
|
|
105
|
+
)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Carousel
|
|
109
|
+
For sending products via WhatsApp carousel.
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from weni_utils.tools.plugins import Carousel
|
|
113
|
+
|
|
114
|
+
concierge = ProductConcierge(
|
|
115
|
+
plugins=[
|
|
116
|
+
Carousel(
|
|
117
|
+
weni_token="your-token",
|
|
118
|
+
max_items=10,
|
|
119
|
+
auto_send=True
|
|
120
|
+
)
|
|
121
|
+
]
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
result = concierge.search(
|
|
125
|
+
product_name="shirt",
|
|
126
|
+
contact_info={"urn": "whatsapp:5511999999999"}
|
|
127
|
+
)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### CAPI (Meta Conversions API)
|
|
131
|
+
For sending conversion events to Meta.
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from weni_utils.tools.plugins import CAPI
|
|
135
|
+
|
|
136
|
+
concierge = ProductConcierge(
|
|
137
|
+
plugins=[
|
|
138
|
+
CAPI(event_type="lead", auto_send=True)
|
|
139
|
+
]
|
|
140
|
+
)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### WeniFlowTrigger
|
|
144
|
+
For triggering Weni flows.
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from weni_utils.tools.plugins import WeniFlowTrigger
|
|
148
|
+
|
|
149
|
+
concierge = ProductConcierge(
|
|
150
|
+
plugins=[
|
|
151
|
+
WeniFlowTrigger(
|
|
152
|
+
flow_uuid="flow-uuid",
|
|
153
|
+
trigger_once=True
|
|
154
|
+
)
|
|
155
|
+
]
|
|
156
|
+
)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## 🏗️ Architecture
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
163
|
+
│ ProductConcierge │
|
|
164
|
+
│ (Orchestrates entire flow) │
|
|
165
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
166
|
+
│
|
|
167
|
+
┌────────────────────┼────────────────────┐
|
|
168
|
+
│ │ │
|
|
169
|
+
▼ ▼ ▼
|
|
170
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
171
|
+
│ VTEXClient │ │ StockManager │ │ Plugins │
|
|
172
|
+
│ │ │ │ │ │
|
|
173
|
+
│ • search() │ │ • check() │ │ • before_search │
|
|
174
|
+
│ • simulate() │ │ • filter() │ │ • after_search │
|
|
175
|
+
│ • get_region() │ │ • limit_size() │ │ • enrich() │
|
|
176
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## 🔄 Execution Flow
|
|
180
|
+
|
|
181
|
+
1. **before_search** - Plugins modify context (e.g., get region_id)
|
|
182
|
+
2. **intelligent_search** - Search products in VTEX
|
|
183
|
+
3. **after_search** - Plugins filter/modify products
|
|
184
|
+
4. **check_availability** - Verify stock
|
|
185
|
+
5. **after_stock_check** - Plugins enrich (e.g., wholesale prices)
|
|
186
|
+
6. **filter_products** - Filter only products with stock
|
|
187
|
+
7. **enrich_products** - Plugins add extra data
|
|
188
|
+
8. **finalize_result** - Plugins perform final actions (e.g., send events)
|
|
189
|
+
|
|
190
|
+
## 🤝 Creating a New Plugin
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
from weni_utils.tools.plugins import PluginBase
|
|
194
|
+
|
|
195
|
+
class MyPlugin(PluginBase):
|
|
196
|
+
name = "my_plugin"
|
|
197
|
+
|
|
198
|
+
def before_search(self, context, client):
|
|
199
|
+
# Modify context before search
|
|
200
|
+
return context
|
|
201
|
+
|
|
202
|
+
def after_search(self, products, context, client):
|
|
203
|
+
# Modify products after search
|
|
204
|
+
return products
|
|
205
|
+
|
|
206
|
+
def after_stock_check(self, products_with_stock, context, client):
|
|
207
|
+
# Enrich products after stock check
|
|
208
|
+
return products_with_stock
|
|
209
|
+
|
|
210
|
+
def finalize_result(self, result, context):
|
|
211
|
+
# Final modification before return
|
|
212
|
+
return result
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## 📝 License
|
|
216
|
+
|
|
217
|
+
MIT License - Weni AI
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "weni-utils-tools"
|
|
7
|
+
version = "0.0.1"
|
|
8
|
+
description = "Modular tools library for AI agents on the Weni platform"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Weni AI", email = "dev@weni.ai"}
|
|
14
|
+
]
|
|
15
|
+
maintainers = [
|
|
16
|
+
{name = "Weni AI", email = "dev@weni.ai"}
|
|
17
|
+
]
|
|
18
|
+
keywords = [
|
|
19
|
+
"weni",
|
|
20
|
+
"vtex",
|
|
21
|
+
"ecommerce",
|
|
22
|
+
"ai-agent",
|
|
23
|
+
"chatbot",
|
|
24
|
+
"whatsapp",
|
|
25
|
+
"product-search",
|
|
26
|
+
"intelligent-search",
|
|
27
|
+
"tools"
|
|
28
|
+
]
|
|
29
|
+
classifiers = [
|
|
30
|
+
"Development Status :: 3 - Alpha",
|
|
31
|
+
"Intended Audience :: Developers",
|
|
32
|
+
"License :: OSI Approved :: MIT License",
|
|
33
|
+
"Operating System :: OS Independent",
|
|
34
|
+
"Programming Language :: Python :: 3",
|
|
35
|
+
"Programming Language :: Python :: 3.9",
|
|
36
|
+
"Programming Language :: Python :: 3.10",
|
|
37
|
+
"Programming Language :: Python :: 3.11",
|
|
38
|
+
"Programming Language :: Python :: 3.12",
|
|
39
|
+
"Programming Language :: Python :: 3.13",
|
|
40
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
41
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
42
|
+
"Topic :: Communications :: Chat",
|
|
43
|
+
"Typing :: Typed"
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
dependencies = [
|
|
47
|
+
"requests>=2.28.0,<3.0.0",
|
|
48
|
+
"pytz>=2023.3"
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[project.optional-dependencies]
|
|
52
|
+
dev = [
|
|
53
|
+
"pytest>=7.0.0",
|
|
54
|
+
"pytest-cov>=4.0.0",
|
|
55
|
+
"pytest-mock>=3.10.0",
|
|
56
|
+
"responses>=0.23.0",
|
|
57
|
+
"black==24.10.0",
|
|
58
|
+
"isort==5.13.2",
|
|
59
|
+
"mypy>=1.0.0",
|
|
60
|
+
"types-requests>=2.28.0",
|
|
61
|
+
"ruff>=0.1.0"
|
|
62
|
+
]
|
|
63
|
+
docs = [
|
|
64
|
+
"sphinx>=6.0.0",
|
|
65
|
+
"sphinx-rtd-theme>=1.2.0",
|
|
66
|
+
"myst-parser>=1.0.0"
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
[project.urls]
|
|
70
|
+
Homepage = "https://github.com/weni-ai/tools-utils"
|
|
71
|
+
Documentation = "https://github.com/weni-ai/tools-utils#readme"
|
|
72
|
+
Repository = "https://github.com/weni-ai/tools-utils.git"
|
|
73
|
+
Issues = "https://github.com/weni-ai/tools-utils/issues"
|
|
74
|
+
Changelog = "https://github.com/weni-ai/tools-utils/blob/main/CHANGELOG.md"
|
|
75
|
+
|
|
76
|
+
[tool.setuptools]
|
|
77
|
+
package-dir = {"" = "src"}
|
|
78
|
+
include-package-data = true
|
|
79
|
+
|
|
80
|
+
[tool.setuptools.packages.find]
|
|
81
|
+
where = ["src"]
|
|
82
|
+
include = ["weni_utils*"]
|
|
83
|
+
|
|
84
|
+
[tool.setuptools.package-data]
|
|
85
|
+
"weni_utils.tools" = ["py.typed"]
|
|
86
|
+
|
|
87
|
+
[tool.black]
|
|
88
|
+
line-length = 100
|
|
89
|
+
target-version = ["py39", "py310", "py311", "py312"]
|
|
90
|
+
|
|
91
|
+
[tool.isort]
|
|
92
|
+
profile = "black"
|
|
93
|
+
line_length = 100
|
|
94
|
+
known_first_party = ["weni_utils"]
|
|
95
|
+
skip_gitignore = true
|
|
96
|
+
|
|
97
|
+
[tool.mypy]
|
|
98
|
+
python_version = "3.9"
|
|
99
|
+
warn_return_any = false
|
|
100
|
+
warn_unused_configs = true
|
|
101
|
+
disallow_untyped_defs = false
|
|
102
|
+
disallow_incomplete_defs = false
|
|
103
|
+
check_untyped_defs = false
|
|
104
|
+
no_implicit_optional = false
|
|
105
|
+
strict_optional = false
|
|
106
|
+
allow_untyped_globals = true
|
|
107
|
+
ignore_errors = false
|
|
108
|
+
|
|
109
|
+
[[tool.mypy.overrides]]
|
|
110
|
+
module = "weni_utils.*"
|
|
111
|
+
ignore_errors = true
|
|
112
|
+
|
|
113
|
+
[tool.ruff]
|
|
114
|
+
line-length = 100
|
|
115
|
+
target-version = "py39"
|
|
116
|
+
|
|
117
|
+
[tool.pytest.ini_options]
|
|
118
|
+
testpaths = ["tests"]
|
|
119
|
+
python_files = ["test_*.py"]
|
|
120
|
+
python_functions = ["test_*"]
|
|
121
|
+
addopts = "-v --cov=weni_utils --cov-report=term-missing"
|
|
122
|
+
|
|
123
|
+
[tool.coverage.run]
|
|
124
|
+
source = ["src/weni_utils"]
|
|
125
|
+
branch = true
|