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.
@@ -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 (critical for @lid numbers)",
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
- # Optimization: treating @lid
127
- # If the selected JID is an LID, verify if we have an ALT available
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
- # Normalize the key inside data so the rest of the app uses the "best" JID
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
- # CRITICAL FIX: Check if there's a stored remoteJid for this contact
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
- # CRITICAL FIX: Check if there's a stored remoteJid for this contact
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
- # CRITICAL FIX: Check if there's a stored remoteJid for this contact
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
- For Brazilian numbers, we now test with @lid format instead.
1601
-
1602
- Brazilian mobile format: 55 + DDD (2 digits) + 9 + 8 digits = 13 digits total
1603
- Example: 5534998137839@lid
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 @s.whatsapp.net or @lid suffix if present
1608
- if "@s.whatsapp.net" in phone:
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
- # Handle different input formats
1616
+ # Add country code 55 if not present
1617
1617
  if not phone.startswith("55"):
1618
- # No country code - add it
1619
- if len(phone) == 11:
1620
- # Format: DDD (2) + 9 (1) + 8 digits = 11 digits
1621
- # Example: 34998137839 -> 5534998137839
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
- # TESTING: Use @lid for Brazilian numbers (country code 55) instead of @s.whatsapp.net
1664
- if not phone.endswith("@lid") and not phone.endswith("@s.whatsapp.net"):
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
- # CRITICAL FIX: Store remoteJid for @lid numbers
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=payload.data.key.remoteJidAlt or ""
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
- # CRITICAL FIX: Store the actual remoteJid for @lid numbers
3495
- # This is needed to send messages back to the correct WhatsApp JID
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"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentle
3
- Version: 0.9.41
3
+ Version: 0.9.42
4
4
  Summary: ...
5
5
  Author-email: Arthur Brenno <64020210+arthurbrenno@users.noreply.github.com>
6
6
  License-File: LICENSE
@@ -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=o3fa5iSD-26CcmcMw0pzU0aS9ju1Mm9vD9ZHWwfEI9o,169964
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=QtGAJKOF1ykZycsNDld25gk-JUeg3uV7hNXx0ZXO0Rg,1217
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=qtLlJJ1RxHkj89bU9tFHplv9qcV_5SqIsp1GOzQFCEU,6207
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=6nIItw8dwBEuWDa8lb3qaEthN4ywbSRJgYyY49EXowI,69043
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.41.dist-info/METADATA,sha256=AYTLK3-J2KRaGK_AwjNjyzxsUlgOJciq4GxvsPgW2wI,86879
1022
- agentle-0.9.41.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
1023
- agentle-0.9.41.dist-info/licenses/LICENSE,sha256=T90S9vqRS6qP-voULxAcvwEs558wRRo6dHuZrjgcOUI,1085
1024
- agentle-0.9.41.dist-info/RECORD,,
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,,