agentle 0.9.41__py3-none-any.whl → 0.9.42__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.
- agentle/agents/whatsapp/models/whatsapp_message.py +1 -1
- agentle/agents/whatsapp/models/whatsapp_webhook_payload.py +5 -15
- agentle/agents/whatsapp/providers/evolution/evolution_api_provider.py +21 -68
- agentle/agents/whatsapp/whatsapp_bot.py +11 -11
- {agentle-0.9.41.dist-info → agentle-0.9.42.dist-info}/METADATA +1 -1
- {agentle-0.9.41.dist-info → agentle-0.9.42.dist-info}/RECORD +8 -8
- {agentle-0.9.41.dist-info → agentle-0.9.42.dist-info}/WHEEL +0 -0
- {agentle-0.9.41.dist-info → agentle-0.9.42.dist-info}/licenses/LICENSE +0 -0
|
@@ -24,7 +24,7 @@ class WhatsAppMessage(BaseModel):
|
|
|
24
24
|
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
25
25
|
remote_jid: str | None = Field(
|
|
26
26
|
default=None,
|
|
27
|
-
description="Actual WhatsApp JID for sending messages
|
|
27
|
+
description="Actual WhatsApp JID for sending messages back to the contact",
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
@override
|
|
@@ -87,8 +87,6 @@ class WhatsAppWebhookPayload(BaseModel):
|
|
|
87
87
|
|
|
88
88
|
# Initialize data if missing but root fields are present
|
|
89
89
|
if not self.data and (self.remoteJid or self.remoteJidAlt):
|
|
90
|
-
# This is a bit of a hack to ensure we have a structure to hold the key
|
|
91
|
-
# if we only got root level JIDs
|
|
92
90
|
from agentle.agents.whatsapp.models.key import Key
|
|
93
91
|
from agentle.agents.whatsapp.models.data import Data
|
|
94
92
|
|
|
@@ -120,26 +118,18 @@ class WhatsAppWebhookPayload(BaseModel):
|
|
|
120
118
|
selected_jid = next((c for c in candidates if c), None)
|
|
121
119
|
|
|
122
120
|
if not selected_jid:
|
|
123
|
-
# Should we raise? For now let's just return and let validation fail if strict
|
|
124
121
|
return
|
|
125
|
-
|
|
126
|
-
#
|
|
127
|
-
#
|
|
122
|
+
|
|
123
|
+
# Handle @lid: Evolution API sometimes sends @lid in remoteJid,
|
|
124
|
+
# but provides the correct @s.whatsapp.net format in remoteJidAlt.
|
|
125
|
+
# In this case, prefer remoteJidAlt.
|
|
128
126
|
if "@lid" in selected_jid:
|
|
129
|
-
# If we selected a main JID that is LID, try to find an Alt
|
|
130
|
-
# candidates for alt: key.remoteJidAlt, self.remoteJidAlt
|
|
131
127
|
alt_candidates = [key.remoteJidAlt, self.remoteJidAlt]
|
|
132
128
|
alt_jid = next((c for c in alt_candidates if c), None)
|
|
133
|
-
|
|
134
129
|
if alt_jid:
|
|
135
130
|
selected_jid = alt_jid
|
|
136
|
-
elif not key.remoteJidAlt and not self.remoteJidAlt:
|
|
137
|
-
# If we have an LID but no ALT, we might be in trouble depending on the use case,
|
|
138
|
-
# but we proceed with what we have or raise as before
|
|
139
|
-
# The original code raised ValueError here
|
|
140
|
-
pass
|
|
141
131
|
|
|
142
132
|
self.phone_number_id = selected_jid.split("@")[0]
|
|
143
133
|
|
|
144
|
-
#
|
|
134
|
+
# Store the selected JID in data.key for downstream use
|
|
145
135
|
self.data.key.remoteJid = selected_jid
|
|
@@ -752,8 +752,7 @@ class EvolutionAPIProvider(WhatsAppProvider):
|
|
|
752
752
|
logger.debug(f"Message is quoting message ID: {quoted_message_id}")
|
|
753
753
|
|
|
754
754
|
try:
|
|
755
|
-
#
|
|
756
|
-
# This is essential for @lid numbers (Brazilian WhatsApp contacts)
|
|
755
|
+
# Check if there's a stored remoteJid for this contact
|
|
757
756
|
session = await self.get_session(to)
|
|
758
757
|
remote_jid = session.context_data.get("remote_jid") if session else None
|
|
759
758
|
|
|
@@ -1117,8 +1116,7 @@ class EvolutionAPIProvider(WhatsAppProvider):
|
|
|
1117
1116
|
logger.debug(f"Sending typing indicator to {to} for {duration}s")
|
|
1118
1117
|
|
|
1119
1118
|
try:
|
|
1120
|
-
#
|
|
1121
|
-
# This is essential for @lid numbers (Brazilian WhatsApp contacts)
|
|
1119
|
+
# Check if there's a stored remoteJid for this contact
|
|
1122
1120
|
session = await self.get_session(to)
|
|
1123
1121
|
remote_jid = session.context_data.get("remote_jid") if session else None
|
|
1124
1122
|
|
|
@@ -1179,8 +1177,7 @@ class EvolutionAPIProvider(WhatsAppProvider):
|
|
|
1179
1177
|
logger.debug(f"Sending recording indicator to {to} for {duration}s")
|
|
1180
1178
|
|
|
1181
1179
|
try:
|
|
1182
|
-
#
|
|
1183
|
-
# This is essential for @lid numbers (Brazilian WhatsApp contacts)
|
|
1180
|
+
# Check if there's a stored remoteJid for this contact
|
|
1184
1181
|
session = await self.get_session(to)
|
|
1185
1182
|
remote_jid = session.context_data.get("remote_jid") if session else None
|
|
1186
1183
|
|
|
@@ -1597,78 +1594,34 @@ class EvolutionAPIProvider(WhatsAppProvider):
|
|
|
1597
1594
|
Normalize phone number to Evolution API format.
|
|
1598
1595
|
|
|
1599
1596
|
Evolution API expects phone numbers in the format: countrycode+number@s.whatsapp.net
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1597
|
+
|
|
1598
|
+
This function:
|
|
1599
|
+
- Removes any existing suffix (@s.whatsapp.net, @lid, etc.)
|
|
1600
|
+
- Strips non-numeric characters
|
|
1601
|
+
- Adds country code 55 if not present
|
|
1602
|
+
- Appends @s.whatsapp.net suffix
|
|
1603
|
+
|
|
1604
|
+
NOTE: This function does NOT modify the number itself (no '9' insertion).
|
|
1605
|
+
The number is sent exactly as provided by the user/webhook.
|
|
1604
1606
|
"""
|
|
1605
1607
|
original_phone = phone
|
|
1606
1608
|
|
|
1607
|
-
# Remove
|
|
1608
|
-
if "@
|
|
1609
|
-
phone = phone.split("@")[0]
|
|
1610
|
-
elif "@lid" in phone:
|
|
1609
|
+
# Remove any @ suffix if present
|
|
1610
|
+
if "@" in phone:
|
|
1611
1611
|
phone = phone.split("@")[0]
|
|
1612
1612
|
|
|
1613
1613
|
# Remove non-numeric characters
|
|
1614
1614
|
phone = "".join(c for c in phone if c.isdigit())
|
|
1615
1615
|
|
|
1616
|
-
#
|
|
1616
|
+
# Add country code 55 if not present
|
|
1617
1617
|
if not phone.startswith("55"):
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
phone = "55" + phone
|
|
1623
|
-
logger.debug(
|
|
1624
|
-
f"Added country code 55 to phone: {original_phone} -> {phone}"
|
|
1625
|
-
)
|
|
1626
|
-
elif len(phone) == 10:
|
|
1627
|
-
# Old format without the 9: DDD (2) + 8 digits = 10 digits
|
|
1628
|
-
# Example: 3498137839 -> 5534998137839
|
|
1629
|
-
# Insert '9' after area code (first 2 digits)
|
|
1630
|
-
phone = "55" + phone[:2] + "9" + phone[2:]
|
|
1631
|
-
logger.warning(
|
|
1632
|
-
f"Converted old format phone number: {original_phone} -> {phone}"
|
|
1633
|
-
)
|
|
1634
|
-
else:
|
|
1635
|
-
# Unknown format, but add 55 anyway
|
|
1636
|
-
phone = "55" + phone
|
|
1637
|
-
logger.warning(
|
|
1638
|
-
f"Unknown phone format, added 55: {original_phone} -> {phone}"
|
|
1639
|
-
)
|
|
1640
|
-
|
|
1641
|
-
# Validate Brazilian mobile format
|
|
1642
|
-
if phone.startswith("55"):
|
|
1643
|
-
# Should have 13 digits total: 55 + DDD (2) + 9 + 8 digits
|
|
1644
|
-
if len(phone) == 12:
|
|
1645
|
-
# Missing the '9' after area code
|
|
1646
|
-
# Example: 553498137839 -> 5534998137839
|
|
1647
|
-
# Insert '9' after 55 + DDD (after position 4)
|
|
1648
|
-
phone = phone[:4] + "9" + phone[4:]
|
|
1649
|
-
logger.warning(
|
|
1650
|
-
f"Fixed missing '9' in phone number: {original_phone} -> {phone}"
|
|
1651
|
-
)
|
|
1652
|
-
elif len(phone) != 13:
|
|
1653
|
-
logger.error(
|
|
1654
|
-
f"Invalid Brazilian mobile number length: {phone} (expected 13 digits, got {len(phone)})"
|
|
1655
|
-
)
|
|
1656
|
-
|
|
1657
|
-
# Validate that the 5th digit is '9' (mobile indicator)
|
|
1658
|
-
if len(phone) >= 5 and phone[4] != "9":
|
|
1659
|
-
logger.warning(
|
|
1660
|
-
f"Phone number may be invalid - 5th digit is not '9': {phone}"
|
|
1661
|
-
)
|
|
1618
|
+
phone = "55" + phone
|
|
1619
|
+
logger.debug(
|
|
1620
|
+
f"Added country code 55 to phone: {original_phone} -> {phone}"
|
|
1621
|
+
)
|
|
1662
1622
|
|
|
1663
|
-
#
|
|
1664
|
-
|
|
1665
|
-
if phone.startswith("55"):
|
|
1666
|
-
# Brazilian number - use @lid
|
|
1667
|
-
phone = phone + "@lid"
|
|
1668
|
-
logger.info(f"🧪 TESTING: Using @lid for Brazilian number: {phone}")
|
|
1669
|
-
else:
|
|
1670
|
-
# Non-Brazilian number - use @s.whatsapp.net
|
|
1671
|
-
phone = phone + "@s.whatsapp.net"
|
|
1623
|
+
# Always use @s.whatsapp.net for normal numbers
|
|
1624
|
+
phone = phone + "@s.whatsapp.net"
|
|
1672
1625
|
|
|
1673
1626
|
if original_phone != phone:
|
|
1674
1627
|
logger.info(f"Phone number normalized: {original_phone} -> {phone}")
|
|
@@ -415,7 +415,7 @@ class WhatsAppBot[T_Schema: WhatsAppResponseBase = WhatsAppResponseBase](BaseMod
|
|
|
415
415
|
f"[MESSAGE_HANDLER] Stored custom chat_id in session: {chat_id}"
|
|
416
416
|
)
|
|
417
417
|
|
|
418
|
-
#
|
|
418
|
+
# Store remoteJid for later use when sending messages
|
|
419
419
|
if message.remote_jid:
|
|
420
420
|
session.context_data["remote_jid"] = message.remote_jid
|
|
421
421
|
logger.info(
|
|
@@ -3478,12 +3478,17 @@ class WhatsAppBot[T_Schema: WhatsAppResponseBase = WhatsAppResponseBase](BaseMod
|
|
|
3478
3478
|
|
|
3479
3479
|
logger.info("[MESSAGE_UPSERT] Parsing message from Evolution API data")
|
|
3480
3480
|
# Parse message directly from data (which contains the message info)
|
|
3481
|
+
# When remoteJid contains @lid, use remoteJidAlt which has the correct @s.whatsapp.net format
|
|
3482
|
+
from_number = payload.data.key.remoteJid
|
|
3483
|
+
if "@lid" in payload.data.key.remoteJid and payload.data.key.remoteJidAlt:
|
|
3484
|
+
from_number = payload.data.key.remoteJidAlt
|
|
3485
|
+
logger.info(
|
|
3486
|
+
f"[MESSAGE_UPSERT] 🔄 Using remoteJidAlt instead of @lid: {from_number}"
|
|
3487
|
+
)
|
|
3481
3488
|
|
|
3482
3489
|
message = self._parse_evolution_message_from_data(
|
|
3483
3490
|
data,
|
|
3484
|
-
from_number=
|
|
3485
|
-
if "@lid" in payload.data.key.remoteJid
|
|
3486
|
-
else payload.data.key.remoteJid,
|
|
3491
|
+
from_number=from_number,
|
|
3487
3492
|
)
|
|
3488
3493
|
|
|
3489
3494
|
if message:
|
|
@@ -3491,13 +3496,8 @@ class WhatsAppBot[T_Schema: WhatsAppResponseBase = WhatsAppResponseBase](BaseMod
|
|
|
3491
3496
|
f"[MESSAGE_UPSERT] ✅ Parsed message: {message.id} from {message.from_number}"
|
|
3492
3497
|
)
|
|
3493
3498
|
|
|
3494
|
-
#
|
|
3495
|
-
|
|
3496
|
-
if "@lid" in payload.data.key.remoteJid:
|
|
3497
|
-
logger.info(
|
|
3498
|
-
f"[MESSAGE_UPSERT] 🔑 Detected @lid number. Storing remoteJid: {payload.data.key.remoteJid} for phone: {message.from_number}"
|
|
3499
|
-
)
|
|
3500
|
-
message.remote_jid = payload.data.key.remoteJid
|
|
3499
|
+
# Store the remoteJid for later use when sending messages back
|
|
3500
|
+
message.remote_jid = from_number
|
|
3501
3501
|
|
|
3502
3502
|
logger.info(
|
|
3503
3503
|
f"[MESSAGE_UPSERT] About to call handle_message with {len(self._response_callbacks)} callbacks"
|
|
@@ -137,7 +137,7 @@ agentle/agents/ui/__init__.py,sha256=IjHRV0k2DNwvFrEHebmsXiBvmITE8nQUnsR07h9tVkU
|
|
|
137
137
|
agentle/agents/ui/streamlit.py,sha256=9afICL0cxtG1o2pWh6vH39-NdKiVfADKiXo405F2aB0,42829
|
|
138
138
|
agentle/agents/whatsapp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
139
139
|
agentle/agents/whatsapp/human_delay_calculator.py,sha256=BGCDeoNTPsMn4d_QYmG0BWGCG8SiUJC6Fk295ulAsAk,18268
|
|
140
|
-
agentle/agents/whatsapp/whatsapp_bot.py,sha256=
|
|
140
|
+
agentle/agents/whatsapp/whatsapp_bot.py,sha256=n3GPOI3HfahTrJyDcaNYXNSm8yKJX1xAeUXx0wG0HTw,169926
|
|
141
141
|
agentle/agents/whatsapp/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
142
142
|
agentle/agents/whatsapp/models/audio_message.py,sha256=af2apMWzxKcCtXfQN6U2qfOFoiwRj0nCUrKmrBD0whE,3067
|
|
143
143
|
agentle/agents/whatsapp/models/context_info.py,sha256=sk80KuNE36S6VRnLh7n6UXmzZCXIB4E4lNxnRyVizg8,563
|
|
@@ -158,20 +158,20 @@ agentle/agents/whatsapp/models/whatsapp_document_message.py,sha256=ECM_hXF-3IbC9
|
|
|
158
158
|
agentle/agents/whatsapp/models/whatsapp_image_message.py,sha256=xOAPRRSgqj9gQ2ZZOGdFWfOgtmNpE1W8mIUAmB5YTpo,314
|
|
159
159
|
agentle/agents/whatsapp/models/whatsapp_location_message.py,sha256=CJCJR1DHjrN92OloNopvUteUxUxeEpHlWQSJhj6Ive4,407
|
|
160
160
|
agentle/agents/whatsapp/models/whatsapp_media_message.py,sha256=xmYE0SVdL7UIJuYRWJTfCoGAd5-pyXBnueaxFaECuXg,386
|
|
161
|
-
agentle/agents/whatsapp/models/whatsapp_message.py,sha256=
|
|
161
|
+
agentle/agents/whatsapp/models/whatsapp_message.py,sha256=u0HrWuK--cRNX96avYbiWkInHYYH67TOXI9XSNOS_BI,1209
|
|
162
162
|
agentle/agents/whatsapp/models/whatsapp_message_status.py,sha256=jDWShdvSve5EhkgtDkh1jZmpRVNoXCokv4M6at1eSIU,214
|
|
163
163
|
agentle/agents/whatsapp/models/whatsapp_message_type.py,sha256=GctIGOC1Bc_D_L0ehEmEwgxePFx0ioTEUoBlZEdxdG8,279
|
|
164
164
|
agentle/agents/whatsapp/models/whatsapp_response_base.py,sha256=IIDONx9Ipt593tAZvoc8dPDUISeNH-WOpRP1x_-Q6Gk,1145
|
|
165
165
|
agentle/agents/whatsapp/models/whatsapp_session.py,sha256=9G1HC-A2G9jTdpwYy3w9bnYkOGK2vvA7kdYAf32oWMU,15640
|
|
166
166
|
agentle/agents/whatsapp/models/whatsapp_text_message.py,sha256=GpSwFrPC4qpQlVCWKKgYjQJKNv0qvwgYfuoD3ttLzdQ,441
|
|
167
167
|
agentle/agents/whatsapp/models/whatsapp_video_message.py,sha256=-d-4hnkkxyLVNoje3a1pOEAvzWqoCLFcBn70wUpnyXY,346
|
|
168
|
-
agentle/agents/whatsapp/models/whatsapp_webhook_payload.py,sha256=
|
|
168
|
+
agentle/agents/whatsapp/models/whatsapp_webhook_payload.py,sha256=N3ERXDcQKC6Vd5k2nlhlpP1EeYN5v5OsDkIUdeFv9U4,5562
|
|
169
169
|
agentle/agents/whatsapp/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
170
170
|
agentle/agents/whatsapp/providers/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
171
171
|
agentle/agents/whatsapp/providers/base/whatsapp_provider.py,sha256=Iaywrv0xer4fhZprMttC-NP4-rRYdU_45UzIZQ7dkYA,5349
|
|
172
172
|
agentle/agents/whatsapp/providers/evolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
173
173
|
agentle/agents/whatsapp/providers/evolution/evolution_api_config.py,sha256=mc3jVJ1olnFgt7jP6P_eygvUVhN3XYSAYp1ozIxtAsc,1288
|
|
174
|
-
agentle/agents/whatsapp/providers/evolution/evolution_api_provider.py,sha256=
|
|
174
|
+
agentle/agents/whatsapp/providers/evolution/evolution_api_provider.py,sha256=QufRuXBtreBGEfSpfJz1wnQCGjifAu_N9AZUmjyFeyY,66584
|
|
175
175
|
agentle/agents/whatsapp/providers/meta/__init__.py,sha256=ArZ2y9qUALahP2-c0j0ESFKmRjDHiZIurqxYC7MTWA8,1038
|
|
176
176
|
agentle/agents/whatsapp/providers/meta/meta_whatsapp_config.py,sha256=ECzb76Sba0ExrO4NAB7v9HLlgAxsjyTg57mewdVt8EY,1257
|
|
177
177
|
agentle/agents/whatsapp/providers/meta/meta_whatsapp_provider.py,sha256=95xvVrqp6f5Ku49fqOEHUhJUIJPGb1rRvCntoIY2JSM,35953
|
|
@@ -1018,7 +1018,7 @@ agentle/web/actions/scroll.py,sha256=WqVVAORNDK3BL1oASZBPmXJYeSVkPgAOmWA8ibYO82I
|
|
|
1018
1018
|
agentle/web/actions/viewport.py,sha256=KCwm88Pri19Qc6GLHC69HsRxmdJz1gEEAODfggC_fHo,287
|
|
1019
1019
|
agentle/web/actions/wait.py,sha256=IKEywjf-KC4ni9Gkkv4wgc7bY-hk7HwD4F-OFWlyf2w,571
|
|
1020
1020
|
agentle/web/actions/write_text.py,sha256=9mxfHcpKs_L7BsDnJvOYHQwG8M0GWe61SRJAsKk3xQ8,748
|
|
1021
|
-
agentle-0.9.
|
|
1022
|
-
agentle-0.9.
|
|
1023
|
-
agentle-0.9.
|
|
1024
|
-
agentle-0.9.
|
|
1021
|
+
agentle-0.9.42.dist-info/METADATA,sha256=d2ra_dRi9kbEYhixrDlJGsCRuC63r9iviZfgpOOsEk4,86879
|
|
1022
|
+
agentle-0.9.42.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
1023
|
+
agentle-0.9.42.dist-info/licenses/LICENSE,sha256=T90S9vqRS6qP-voULxAcvwEs558wRRo6dHuZrjgcOUI,1085
|
|
1024
|
+
agentle-0.9.42.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|