agentle 0.9.39__py3-none-any.whl → 0.9.40__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.
@@ -98,7 +98,13 @@ class WhatsAppBotConfig(BaseModel):
98
98
  description="Default error message",
99
99
  )
100
100
  welcome_message: str | None = Field(
101
- default=None, description="Message to send on first interaction"
101
+ default=None, description="Message to send on first interaction (or caption if welcome image is set)"
102
+ )
103
+ welcome_image_url: str | None = Field(
104
+ default=None, description="URL of welcome image to send on first interaction"
105
+ )
106
+ welcome_image_base64: str | None = Field(
107
+ default=None, description="Base64-encoded welcome image to send on first interaction (alternative to welcome_image_url)"
102
108
  )
103
109
 
104
110
  # === Message Batching (Simplified) ===
@@ -257,6 +263,8 @@ class WhatsAppBotConfig(BaseModel):
257
263
  max_split_messages: int | None = None,
258
264
  error_message: str | None = None,
259
265
  welcome_message: str | None = None,
266
+ welcome_image_url: str | None = None,
267
+ welcome_image_base64: str | None = None,
260
268
  # Message Batching
261
269
  enable_message_batching: bool | None = None,
262
270
  batch_delay_seconds: float | None = None,
@@ -366,6 +374,10 @@ class WhatsAppBotConfig(BaseModel):
366
374
  overrides["error_message"] = error_message
367
375
  if welcome_message is not None:
368
376
  overrides["welcome_message"] = welcome_message
377
+ if welcome_image_url is not None:
378
+ overrides["welcome_image_url"] = welcome_image_url
379
+ if welcome_image_base64 is not None:
380
+ overrides["welcome_image_base64"] = welcome_image_base64
369
381
 
370
382
  # Message Batching
371
383
  if enable_message_batching is not None:
@@ -1597,15 +1597,18 @@ class EvolutionAPIProvider(WhatsAppProvider):
1597
1597
  Normalize phone number to Evolution API format.
1598
1598
 
1599
1599
  Evolution API expects phone numbers in the format: countrycode+number@s.whatsapp.net
1600
+ For Brazilian numbers, we now test with @lid format instead.
1600
1601
 
1601
1602
  Brazilian mobile format: 55 + DDD (2 digits) + 9 + 8 digits = 13 digits total
1602
- Example: 5534998137839@s.whatsapp.net
1603
+ Example: 5534998137839@lid
1603
1604
  """
1604
1605
  original_phone = phone
1605
1606
 
1606
- # Remove @s.whatsapp.net suffix if present
1607
+ # Remove @s.whatsapp.net or @lid suffix if present
1607
1608
  if "@s.whatsapp.net" in phone:
1608
1609
  phone = phone.split("@")[0]
1610
+ elif "@lid" in phone:
1611
+ phone = phone.split("@")[0]
1609
1612
 
1610
1613
  # Remove non-numeric characters
1611
1614
  phone = "".join(c for c in phone if c.isdigit())
@@ -1657,9 +1660,15 @@ class EvolutionAPIProvider(WhatsAppProvider):
1657
1660
  f"Phone number may be invalid - 5th digit is not '9': {phone}"
1658
1661
  )
1659
1662
 
1660
- # Add @s.whatsapp.net suffix if not present
1661
- if not phone.endswith("@s.whatsapp.net"):
1662
- phone = phone + "@s.whatsapp.net"
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"
1663
1672
 
1664
1673
  if original_phone != phone:
1665
1674
  logger.info(f"Phone number normalized: {original_phone} -> {phone}")
@@ -431,23 +431,117 @@ class WhatsAppBot[T_Schema: WhatsAppResponseBase = WhatsAppResponseBase](BaseMod
431
431
  f"[MESSAGE_HANDLER] Effective chat_id para conversação: {effective_chat_id}"
432
432
  )
433
433
 
434
- # Check welcome message for first interaction
434
+ # Check welcome message/image for first interaction
435
435
  if (
436
436
  await cast(
437
437
  ConversationStore, self.agent.conversation_store
438
438
  ).get_conversation_history_length(effective_chat_id)
439
439
  == 0
440
- and self.config.welcome_message
440
+ and (
441
+ self.config.welcome_message
442
+ or self.config.welcome_image_url
443
+ or self.config.welcome_image_base64
444
+ )
441
445
  ):
442
446
  logger.info(
443
- f"[WELCOME] Sending welcome message to {message.from_number}"
447
+ f"[WELCOME] Sending welcome message/image to {message.from_number}"
444
448
  )
445
- formatted_welcome = self._format_whatsapp_markdown(
446
- self.config.welcome_message
447
- )
448
- await self.provider.send_text_message(
449
- message.from_number, formatted_welcome
449
+
450
+ # Determine if we're sending an image or text
451
+ has_welcome_image = (
452
+ self.config.welcome_image_url or self.config.welcome_image_base64
450
453
  )
454
+
455
+ if has_welcome_image:
456
+ # Prepare caption from welcome_message if available
457
+ caption = None
458
+ if self.config.welcome_message:
459
+ caption = self._format_whatsapp_markdown(
460
+ self.config.welcome_message
461
+ )
462
+
463
+ # Handle welcome image via URL
464
+ if self.config.welcome_image_url:
465
+ logger.info(
466
+ f"[WELCOME] Sending welcome image from URL to {message.from_number}"
467
+ )
468
+ await self.provider.send_media_message(
469
+ to=message.from_number,
470
+ media_url=self.config.welcome_image_url,
471
+ media_type="image",
472
+ caption=caption,
473
+ )
474
+ # Handle welcome image via base64
475
+ elif self.config.welcome_image_base64:
476
+ # Try to upload base64 to file storage if available
477
+ image_url = None
478
+ if self.file_storage_manager:
479
+ try:
480
+ import base64
481
+ import time
482
+
483
+ logger.info(
484
+ "[WELCOME] Uploading base64 welcome image to file storage"
485
+ )
486
+
487
+ # Decode base64 to bytes
488
+ image_bytes = base64.b64decode(
489
+ self.config.welcome_image_base64
490
+ )
491
+
492
+ # Generate unique filename
493
+ timestamp = int(time.time())
494
+ filename = f"welcome_image_{timestamp}.jpg"
495
+
496
+ # Upload to storage
497
+ image_url = await self.file_storage_manager.upload_file(
498
+ file_data=image_bytes,
499
+ filename=filename,
500
+ mime_type="image/jpeg",
501
+ )
502
+
503
+ logger.info(
504
+ f"[WELCOME] Welcome image uploaded to storage: {image_url}"
505
+ )
506
+ except Exception as e:
507
+ logger.warning(
508
+ f"[WELCOME] Failed to upload welcome image to storage: {e}"
509
+ )
510
+ image_url = None
511
+
512
+ # Send image via URL if upload succeeded, otherwise send text fallback
513
+ if image_url:
514
+ logger.info(
515
+ f"[WELCOME] Sending uploaded welcome image to {message.from_number}"
516
+ )
517
+ await self.provider.send_media_message(
518
+ to=message.from_number,
519
+ media_url=image_url,
520
+ media_type="image",
521
+ caption=caption,
522
+ )
523
+ else:
524
+ # Fallback to text if base64 upload failed and no URL available
525
+ logger.warning(
526
+ "[WELCOME] Could not send welcome image (base64 upload failed and no URL), falling back to text"
527
+ )
528
+ if caption:
529
+ await self.provider.send_text_message(
530
+ message.from_number, caption
531
+ )
532
+ else:
533
+ logger.warning(
534
+ "[WELCOME] No caption available, skipping welcome message"
535
+ )
536
+ else:
537
+ # Send text-only welcome message (backward compatible)
538
+ formatted_welcome = self._format_whatsapp_markdown(
539
+ self.config.welcome_message
540
+ )
541
+ await self.provider.send_text_message(
542
+ message.from_number, formatted_welcome
543
+ )
544
+
451
545
  session.message_count += 1
452
546
  await self.provider.update_session(session)
453
547
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentle
3
- Version: 0.9.39
3
+ Version: 0.9.40
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=3ohpjdjeeX0MPxrcllLamT8lfi6y2UjSzFxYTeVLQ-o,165392
140
+ agentle/agents/whatsapp/whatsapp_bot.py,sha256=o3fa5iSD-26CcmcMw0pzU0aS9ju1Mm9vD9ZHWwfEI9o,169964
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
@@ -152,7 +152,7 @@ agentle/agents/whatsapp/models/message_context_info.py,sha256=msCSuu8uMN3G9GDaXd
152
152
  agentle/agents/whatsapp/models/quoted_message.py,sha256=QC4sp7eLPE9g9i-_f3avb0sDO7gKpkzZR2qkbxqptts,1073
153
153
  agentle/agents/whatsapp/models/video_message.py,sha256=0s4ak68euff25a_tXvYscKCFn7rQj8Rj6U89rupQnO0,3697
154
154
  agentle/agents/whatsapp/models/whatsapp_audio_message.py,sha256=AAcnjzJC1O5VjyWZaSWpG_tmZFc2-CdcPn9abjyLrpc,378
155
- agentle/agents/whatsapp/models/whatsapp_bot_config.py,sha256=hkbOAdSZbSt634mZEARuPQSer7wf3biL7dL9TFW-a7o,37164
155
+ agentle/agents/whatsapp/models/whatsapp_bot_config.py,sha256=-YLnzFOUlNwNvROTOlJ1W8RLNwnJ3irXI3znaMo7UnI,37831
156
156
  agentle/agents/whatsapp/models/whatsapp_contact.py,sha256=6iO6xmFs7z9hd1N9kZzGyNHYvCaUoCHn3Yi1DAJN4YU,240
157
157
  agentle/agents/whatsapp/models/whatsapp_document_message.py,sha256=ECM_hXF-3IbC9itbtZI0eA_XRNXFVefw9Mr-Lo_lrH0,323
158
158
  agentle/agents/whatsapp/models/whatsapp_image_message.py,sha256=xOAPRRSgqj9gQ2ZZOGdFWfOgtmNpE1W8mIUAmB5YTpo,314
@@ -171,7 +171,7 @@ agentle/agents/whatsapp/providers/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JC
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=rE0OwJma7mnLiPXcK2oBFFmr69zQxTRfmHNrEvj4NoU,68539
174
+ agentle/agents/whatsapp/providers/evolution/evolution_api_provider.py,sha256=6nIItw8dwBEuWDa8lb3qaEthN4ywbSRJgYyY49EXowI,69043
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.39.dist-info/METADATA,sha256=koWpbsp8gWkx7AtBogPGlGRfoQQ6lo2_A7v-gBJisZs,86879
1022
- agentle-0.9.39.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1023
- agentle-0.9.39.dist-info/licenses/LICENSE,sha256=T90S9vqRS6qP-voULxAcvwEs558wRRo6dHuZrjgcOUI,1085
1024
- agentle-0.9.39.dist-info/RECORD,,
1021
+ agentle-0.9.40.dist-info/METADATA,sha256=gPlRkCIx8kIOt4O70scPrcbgMuVbGXGLjc67cW2rQeU,86879
1022
+ agentle-0.9.40.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
1023
+ agentle-0.9.40.dist-info/licenses/LICENSE,sha256=T90S9vqRS6qP-voULxAcvwEs558wRRo6dHuZrjgcOUI,1085
1024
+ agentle-0.9.40.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any