abstractassistant 0.3.0__py3-none-any.whl → 0.3.2__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.
abstractassistant/app.py CHANGED
@@ -526,6 +526,11 @@ class AbstractAssistantApp:
526
526
  voice_manager.stop()
527
527
  if self.debug:
528
528
  print("⏹ Voice stopped")
529
+
530
+ # Update icon status to ready since v0.5.1 callback won't fire for manual stops
531
+ self.update_icon_status("ready")
532
+ if self.debug:
533
+ print("🔄 Icon status set to ready after manual voice stop")
529
534
 
530
535
  # Always show chat bubble on double click
531
536
  if self.debug:
@@ -359,6 +359,24 @@ class iPhoneMessagesDialog:
359
359
  layout.addStretch()
360
360
 
361
361
  bubble_layout.addWidget(content_label)
362
+
363
+ # Add file attachment indicator if files were attached to this message
364
+ attached_files = msg.get('attached_files', [])
365
+ if attached_files:
366
+ file_indicator = QLabel(f"📎 {len(attached_files)} file{'s' if len(attached_files) > 1 else ''}")
367
+ file_indicator.setStyleSheet("""
368
+ QLabel {
369
+ background: transparent;
370
+ color: rgba(255, 255, 255, 0.7);
371
+ font-size: 11px;
372
+ font-weight: 500;
373
+ font-family: "Helvetica Neue", "Helvetica", Arial, sans-serif;
374
+ padding: 2px 0px;
375
+ margin: 0px;
376
+ }
377
+ """)
378
+ bubble_layout.addWidget(file_indicator)
379
+
362
380
  main_layout.addWidget(container)
363
381
 
364
382
  # Add timestamp below bubble (iPhone style)
@@ -289,6 +289,9 @@ class QtChatBubble(QWidget):
289
289
  # Attached files for media handling (AbstractCore 2.4.5+)
290
290
  self.attached_files: List[str] = []
291
291
 
292
+ # Track file attachments per message for history display
293
+ self.message_file_attachments: Dict[int, List[str]] = {}
294
+
292
295
  # Initialize new manager classes
293
296
  self.provider_manager = None
294
297
  self.tts_state_manager = None
@@ -360,7 +363,10 @@ class QtChatBubble(QWidget):
360
363
  )
361
364
 
362
365
  # Set optimal size for modern chat interface - much wider to nearly touch screen edge
363
- self.setFixedSize(630, 196) # Increased width from 540 to 700 for better text display
366
+ # Initial size - will be adjusted dynamically based on file attachments
367
+ self.base_width = 630
368
+ self.base_height = 196
369
+ self.setFixedSize(self.base_width, self.base_height)
364
370
  self.position_near_tray()
365
371
 
366
372
  # Main layout with minimal spacing
@@ -440,10 +446,7 @@ class QtChatBubble(QWidget):
440
446
  self.full_voice_toggle.toggled.connect(self.on_full_voice_toggled)
441
447
  header_layout.addWidget(self.full_voice_toggle)
442
448
 
443
- # Add prominent voice control panel when TTS is active
444
- self.voice_control_panel = self.create_voice_control_panel()
445
- header_layout.addWidget(self.voice_control_panel)
446
- self.voice_control_panel.hide() # Hidden initially
449
+ # Voice control panel removed - not needed
447
450
 
448
451
  header_layout.addStretch()
449
452
 
@@ -565,8 +568,8 @@ class QtChatBubble(QWidget):
565
568
  }
566
569
  """)
567
570
  self.attached_files_layout = QHBoxLayout(self.attached_files_container)
568
- self.attached_files_layout.setContentsMargins(4, 4, 4, 4)
569
- self.attached_files_layout.setSpacing(4)
571
+ self.attached_files_layout.setContentsMargins(2, 2, 2, 2)
572
+ self.attached_files_layout.setSpacing(2)
570
573
  self.attached_files_container.hide() # Initially hidden
571
574
  input_layout.addWidget(self.attached_files_container)
572
575
  layout.addWidget(self.input_container)
@@ -1140,6 +1143,7 @@ class QtChatBubble(QWidget):
1140
1143
 
1141
1144
  if not self.attached_files:
1142
1145
  self.attached_files_container.hide()
1146
+ self._adjust_window_size_for_attachments()
1143
1147
  return
1144
1148
 
1145
1149
  # Show container and add file chips
@@ -1155,14 +1159,14 @@ class QtChatBubble(QWidget):
1155
1159
  QFrame {
1156
1160
  background: rgba(0, 102, 204, 0.2);
1157
1161
  border: 1px solid rgba(0, 102, 204, 0.4);
1158
- border-radius: 10px;
1159
- padding: 2px 8px;
1162
+ border-radius: 6px;
1163
+ padding: 1px 4px;
1160
1164
  }
1161
1165
  """)
1162
1166
 
1163
1167
  chip_layout = QHBoxLayout(file_chip)
1164
- chip_layout.setContentsMargins(4, 2, 4, 2)
1165
- chip_layout.setSpacing(4)
1168
+ chip_layout.setContentsMargins(2, 1, 2, 1)
1169
+ chip_layout.setSpacing(2)
1166
1170
 
1167
1171
  # File icon based on type
1168
1172
  ext = os.path.splitext(file_name)[1].lower()
@@ -1182,18 +1186,18 @@ class QtChatBubble(QWidget):
1182
1186
  icon = "📎"
1183
1187
 
1184
1188
  file_label = QLabel(f"{icon} {file_name[:20]}{'...' if len(file_name) > 20 else ''}")
1185
- file_label.setStyleSheet("background: transparent; border: none; color: rgba(255, 255, 255, 0.9); font-size: 10px;")
1189
+ file_label.setStyleSheet("background: transparent; border: none; color: rgba(255, 255, 255, 0.9); font-size: 8px;")
1186
1190
  chip_layout.addWidget(file_label)
1187
1191
 
1188
1192
  # Remove button
1189
1193
  remove_btn = QPushButton("✕")
1190
- remove_btn.setFixedSize(16, 16)
1194
+ remove_btn.setFixedSize(12, 12)
1191
1195
  remove_btn.setStyleSheet("""
1192
1196
  QPushButton {
1193
1197
  background: transparent;
1194
1198
  border: none;
1195
1199
  color: rgba(255, 255, 255, 0.6);
1196
- font-size: 10px;
1200
+ font-size: 8px;
1197
1201
  padding: 0px;
1198
1202
  }
1199
1203
  QPushButton:hover {
@@ -1206,6 +1210,30 @@ class QtChatBubble(QWidget):
1206
1210
  self.attached_files_layout.addWidget(file_chip)
1207
1211
 
1208
1212
  self.attached_files_layout.addStretch()
1213
+
1214
+ # Adjust window size to accommodate file attachments
1215
+ self._adjust_window_size_for_attachments()
1216
+
1217
+ def _adjust_window_size_for_attachments(self):
1218
+ """Dynamically adjust window size based on file attachments presence."""
1219
+ attachment_height = 28 # Height needed for file attachment container (reduced for compact chips)
1220
+
1221
+ if self.attached_files and self.attached_files_container.isVisible():
1222
+ # Files are attached - expand window
1223
+ new_height = self.base_height + attachment_height
1224
+ if self.debug:
1225
+ print(f"📏 Expanding window for attachments: {self.base_height} -> {new_height}")
1226
+ else:
1227
+ # No files attached - use base size
1228
+ new_height = self.base_height
1229
+ if self.debug:
1230
+ print(f"📏 Contracting window (no attachments): -> {new_height}")
1231
+
1232
+ # Apply new size
1233
+ self.setFixedSize(self.base_width, new_height)
1234
+
1235
+ # Reposition to maintain alignment with system tray
1236
+ self.position_near_tray()
1209
1237
 
1210
1238
  def remove_attached_file(self, file_path):
1211
1239
  """Remove a file from the attached files list."""
@@ -1230,12 +1258,18 @@ class QtChatBubble(QWidget):
1230
1258
  # 1. Clear input immediately
1231
1259
  self.input_text.clear()
1232
1260
 
1233
- # 2. Capture attached files before clearing
1261
+ # 2. Capture attached files for sending (but keep them attached)
1234
1262
  media_files = self.attached_files.copy()
1263
+
1264
+ # 3. Store file attachments for this message in our tracking dict
1265
+ # We'll use the message count as a simple key
1266
+ if media_files:
1267
+ message_index = len(self.message_history) # Current message index before adding
1268
+ self.message_file_attachments[message_index] = media_files.copy()
1269
+ if self.debug:
1270
+ print(f"📎 Storing {len(media_files)} file(s) for message index {message_index}")
1235
1271
 
1236
- # 3. Clear attached files display
1237
- self.attached_files.clear()
1238
- self.update_attached_files_display()
1272
+ # Note: We no longer clear attached_files here - they persist for reuse
1239
1273
 
1240
1274
  # 4. Update UI for sending state
1241
1275
  self.send_button.setEnabled(False)
@@ -1403,6 +1437,14 @@ class QtChatBubble(QWidget):
1403
1437
  try:
1404
1438
  self.voice_manager.stop()
1405
1439
  self._update_tts_toggle_state()
1440
+
1441
+ # Manually trigger status update to "ready" since v0.5.1 callback won't fire
1442
+ # when we manually stop the audio
1443
+ if self.status_callback:
1444
+ if self.debug:
1445
+ print("🔊 QtChatBubble: TTS disabled, setting ready status")
1446
+ self.status_callback("ready")
1447
+
1406
1448
  except Exception as e:
1407
1449
  if self.debug:
1408
1450
  if self.debug:
@@ -1507,6 +1549,13 @@ class QtChatBubble(QWidget):
1507
1549
  # Safely update TTS toggle state
1508
1550
  if hasattr(self, '_update_tts_toggle_state'):
1509
1551
  self._update_tts_toggle_state()
1552
+
1553
+ # Manually trigger status update to "ready" since v0.5.1 callback won't fire
1554
+ # when we manually stop the audio
1555
+ if hasattr(self, 'status_callback') and self.status_callback:
1556
+ if self.debug:
1557
+ print("🔊 QtChatBubble: Manually stopped TTS, setting ready status")
1558
+ self.status_callback("ready")
1510
1559
 
1511
1560
  except Exception as e:
1512
1561
  if self.debug:
@@ -1680,7 +1729,10 @@ class QtChatBubble(QWidget):
1680
1729
  self.input_container.hide()
1681
1730
 
1682
1731
  # Update window size to be smaller but maintain wider width
1683
- self.setFixedSize(630, 120) # Reduced width by 10% to match normal size
1732
+ voice_base_height = 120
1733
+ attachment_height = 28 if (self.attached_files and self.attached_files_container.isVisible()) else 0
1734
+ voice_height = voice_base_height + attachment_height
1735
+ self.setFixedSize(self.base_width, voice_height) # Dynamic height for voice mode
1684
1736
 
1685
1737
  def show_text_ui(self):
1686
1738
  """Show the text input interface when exiting Full Voice Mode."""
@@ -1688,8 +1740,8 @@ class QtChatBubble(QWidget):
1688
1740
  if hasattr(self, 'input_container'):
1689
1741
  self.input_container.show()
1690
1742
 
1691
- # Restore normal window size with wider width
1692
- self.setFixedSize(630, 196)
1743
+ # Restore normal window size with wider width - use dynamic sizing
1744
+ self._adjust_window_size_for_attachments()
1693
1745
 
1694
1746
  def update_status(self, status_text: str):
1695
1747
  """Update the status label with the given text."""
@@ -1727,13 +1779,7 @@ class QtChatBubble(QWidget):
1727
1779
  current_state = self.voice_manager.get_state()
1728
1780
  # No longer updating tts_toggle appearance - it's a simple user control
1729
1781
 
1730
- # Show/hide voice control panel based on TTS state
1731
- if hasattr(self, 'voice_control_panel'):
1732
- if current_state in ['speaking', 'paused']:
1733
- self.voice_control_panel.show()
1734
- self._update_voice_control_panel(current_state)
1735
- else:
1736
- self.voice_control_panel.hide()
1782
+ # Voice control panel removed - no longer needed
1737
1783
 
1738
1784
  if self.debug:
1739
1785
  if self.debug:
@@ -1743,89 +1789,7 @@ class QtChatBubble(QWidget):
1743
1789
  if self.debug:
1744
1790
  print(f"❌ Error updating TTS toggle state: {e}")
1745
1791
 
1746
- def create_voice_control_panel(self):
1747
- """Create a prominent voice control panel that appears when TTS is active."""
1748
- panel = QWidget()
1749
- layout = QHBoxLayout()
1750
- layout.setContentsMargins(4, 2, 4, 2)
1751
- layout.setSpacing(4)
1752
-
1753
- # Pause/Resume button
1754
- self.voice_pause_button = QPushButton("⏸")
1755
- self.voice_pause_button.setFixedSize(24, 24)
1756
- self.voice_pause_button.setToolTip("Pause/Resume TTS (Space)")
1757
- self.voice_pause_button.clicked.connect(self.on_tts_single_click)
1758
- self.voice_pause_button.setStyleSheet("""
1759
- QPushButton {
1760
- background: rgba(255, 255, 255, 0.1);
1761
- border: 1px solid rgba(255, 255, 255, 0.2);
1762
- border-radius: 12px;
1763
- font-size: 12px;
1764
- color: rgba(255, 255, 255, 0.9);
1765
- font-weight: bold;
1766
- }
1767
- QPushButton:hover {
1768
- background: rgba(255, 255, 255, 0.2);
1769
- border: 1px solid rgba(255, 255, 255, 0.3);
1770
- }
1771
- QPushButton:pressed {
1772
- background: rgba(255, 255, 255, 0.05);
1773
- }
1774
- """)
1775
- layout.addWidget(self.voice_pause_button)
1776
-
1777
- # Stop button
1778
- self.voice_stop_button = QPushButton("⏹")
1779
- self.voice_stop_button.setFixedSize(24, 24)
1780
- self.voice_stop_button.setToolTip("Stop TTS (Escape)")
1781
- self.voice_stop_button.clicked.connect(self.on_tts_double_click)
1782
- self.voice_stop_button.setStyleSheet("""
1783
- QPushButton {
1784
- background: rgba(255, 100, 100, 0.1);
1785
- border: 1px solid rgba(255, 100, 100, 0.3);
1786
- border-radius: 12px;
1787
- font-size: 12px;
1788
- color: rgba(255, 200, 200, 0.9);
1789
- font-weight: bold;
1790
- }
1791
- QPushButton:hover {
1792
- background: rgba(255, 100, 100, 0.2);
1793
- border: 1px solid rgba(255, 100, 100, 0.4);
1794
- }
1795
- QPushButton:pressed {
1796
- background: rgba(255, 100, 100, 0.05);
1797
- }
1798
- """)
1799
- layout.addWidget(self.voice_stop_button)
1800
-
1801
- # Status text
1802
- self.voice_status_label = QLabel("Speaking...")
1803
- self.voice_status_label.setStyleSheet("""
1804
- QLabel {
1805
- color: rgba(255, 255, 255, 0.8);
1806
- font-size: 10px;
1807
- font-weight: 500;
1808
- padding: 2px 4px;
1809
- }
1810
- """)
1811
- layout.addWidget(self.voice_status_label)
1812
-
1813
- panel.setLayout(layout)
1814
- return panel
1815
-
1816
- def _update_voice_control_panel(self, state):
1817
- """Update the voice control panel based on TTS state."""
1818
- if not hasattr(self, 'voice_control_panel'):
1819
- return
1820
-
1821
- if state == 'speaking':
1822
- self.voice_pause_button.setText("⏸")
1823
- self.voice_pause_button.setToolTip("Pause TTS (Space)")
1824
- self.voice_status_label.setText("Speaking...")
1825
- elif state == 'paused':
1826
- self.voice_pause_button.setText("▶")
1827
- self.voice_pause_button.setToolTip("Resume TTS (Space)")
1828
- self.voice_status_label.setText("Paused")
1792
+ # Voice control panel methods removed - not needed
1829
1793
 
1830
1794
  def setup_keyboard_shortcuts(self):
1831
1795
  """Setup keyboard shortcuts for voice control."""
@@ -1975,7 +1939,7 @@ class QtChatBubble(QWidget):
1975
1939
  reply = QMessageBox.question(
1976
1940
  self,
1977
1941
  "Clear Session",
1978
- "Are you sure you want to clear the current session?\nThis will remove all messages and reset the token count.",
1942
+ "Are you sure you want to clear the current session?\nThis will remove all messages, attached files, and reset the token count.",
1979
1943
  QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
1980
1944
  QMessageBox.StandardButton.No
1981
1945
  )
@@ -1996,9 +1960,14 @@ class QtChatBubble(QWidget):
1996
1960
  self.token_count = 0
1997
1961
  self.update_token_display()
1998
1962
 
1963
+ # Clear attached files as part of session clearing
1964
+ self.attached_files.clear()
1965
+ self.message_file_attachments.clear()
1966
+ self.update_attached_files_display()
1967
+
1999
1968
  if self.debug:
2000
1969
  if self.debug:
2001
- print("🧹 Session cleared")
1970
+ print("🧹 Session cleared (including attached files and file tracking)")
2002
1971
 
2003
1972
  def load_session(self):
2004
1973
  """Load a session using AbstractCore via LLMManager."""
@@ -2131,7 +2100,7 @@ class QtChatBubble(QWidget):
2131
2100
 
2132
2101
  # Convert AbstractCore messages to our format
2133
2102
  self.message_history = []
2134
- for msg in session_messages:
2103
+ for i, msg in enumerate(session_messages):
2135
2104
  # Skip system messages
2136
2105
  if hasattr(msg, 'role') and msg.role == 'system':
2137
2106
  continue
@@ -2141,7 +2110,8 @@ class QtChatBubble(QWidget):
2141
2110
  'type': getattr(msg, 'role', 'unknown'),
2142
2111
  'content': getattr(msg, 'content', str(msg)),
2143
2112
  'provider': self.current_provider,
2144
- 'model': self.current_model
2113
+ 'model': self.current_model,
2114
+ 'attached_files': self.message_file_attachments.get(len(self.message_history), [])
2145
2115
  }
2146
2116
  self.message_history.append(message)
2147
2117
 
@@ -2154,6 +2124,27 @@ class QtChatBubble(QWidget):
2154
2124
  if self.debug:
2155
2125
  print(f"❌ Error updating message history from session: {e}")
2156
2126
 
2127
+ def _rebuild_chat_display(self):
2128
+ """Rebuild chat display after session loading.
2129
+
2130
+ Since the main bubble doesn't have a chat display area, this method
2131
+ updates the history dialog if it's currently open.
2132
+ """
2133
+ try:
2134
+ # If history dialog is open, refresh it with new message history
2135
+ if self.history_dialog and self.history_dialog.isVisible():
2136
+ self.history_dialog.refresh_messages(self.message_history)
2137
+ if self.debug:
2138
+ print("🔄 Refreshed history dialog with loaded session messages")
2139
+
2140
+ # No action needed if history dialog is closed since main bubble has no chat display
2141
+ if self.debug:
2142
+ print("✅ Chat display rebuild completed")
2143
+
2144
+ except Exception as e:
2145
+ if self.debug:
2146
+ print(f"❌ Error rebuilding chat display: {e}")
2147
+
2157
2148
  def _update_token_count_from_session(self):
2158
2149
  """Update token count from AbstractCore session."""
2159
2150
  try:
@@ -324,9 +324,10 @@ class IconGenerator:
324
324
  bar_color = (r, g, b, 255)
325
325
 
326
326
  # Draw 5 vertical bars with different vibration frequencies (like voice visualizer)
327
+ # Made much larger to match other menu bar icons
327
328
  bar_count = 5
328
- bar_width = size * 0.08
329
- bar_spacing = size * 0.12
329
+ bar_width = size * 0.15 # Increased from 0.08 to 0.15 (almost 2x wider)
330
+ bar_spacing = size * 0.18 # Increased from 0.12 to 0.18 (more spacing)
330
331
 
331
332
  for i in range(bar_count):
332
333
  # Each bar has slightly different frequency for realistic voice effect
@@ -334,8 +335,9 @@ class IconGenerator:
334
335
  bar_vibration = math.sin(current_time * bar_freq * 2 * math.pi)
335
336
 
336
337
  # Bar height varies with vibration (like audio visualizer)
337
- base_height = size * 0.15
338
- vibration_height = size * 0.25 * abs(bar_vibration)
338
+ # Made much taller to be more visible
339
+ base_height = size * 0.25 # Increased from 0.15 to 0.25
340
+ vibration_height = size * 0.35 * abs(bar_vibration) # Increased from 0.25 to 0.35
339
341
  total_height = base_height + vibration_height
340
342
 
341
343
  # Position bars horizontally across the icon
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: abstractassistant
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: A sleek (macOS) system tray application providing instant access to LLMs
5
5
  Author-email: Laurent-Philippe Albou <contact@abstractcore.ai>
6
6
  License-Expression: MIT
@@ -28,7 +28,7 @@ Requires-Dist: PyQt5>=5.15.0
28
28
  Requires-Dist: markdown>=3.5.0
29
29
  Requires-Dist: pygments>=2.16.0
30
30
  Requires-Dist: pymdown-extensions>=10.0
31
- Requires-Dist: abstractvoice>=0.5.0
31
+ Requires-Dist: abstractvoice>=0.5.1
32
32
  Requires-Dist: pyperclip>=1.8.2
33
33
  Requires-Dist: plyer>=2.1.0
34
34
  Requires-Dist: tomli>=2.0.0; python_version < "3.11"
@@ -1,6 +1,6 @@
1
1
  setup_macos_app.py,sha256=9dIPr9TipjtgdIhd0MnR2syRNoFyBVMnRsWDW0UCT3A,10736
2
2
  abstractassistant/__init__.py,sha256=homfqMDh6sX2nBROtk6-y72jnrStPph8gEOeT0OjKyU,35
3
- abstractassistant/app.py,sha256=9Dn_2ShT6O5sE3Qf09oh-wKQpLFzKTNVJzZbB0POOYI,40078
3
+ abstractassistant/app.py,sha256=yGFszbaqja_Y1ejSMcVYIcq8f1qdeZpVTb032geI-ZE,40374
4
4
  abstractassistant/cli.py,sha256=SQPxQCLjX-LOlhSEvG302D0AOyxlxo5QM2imxr9wxmc,4385
5
5
  abstractassistant/config.py,sha256=KodfPYTpHtavJyne-h-B-r3kbEt1uusSY8GknGLtDL8,5809
6
6
  abstractassistant/create_app_bundle.py,sha256=LAZdp2C90ikMVd3KPdwNYBYUASbHpypOJIwvx6fQyXM,1698
@@ -10,19 +10,19 @@ abstractassistant/core/llm_manager.py,sha256=hJun-nDfRv9zxv_3tfrHAmVYSYT96E-0zDJ
10
10
  abstractassistant/core/tts_manager.py,sha256=Cxh302EgIycwkWxe7XntmLW-j_WusbJOYRCs3Jms3CU,9892
11
11
  abstractassistant/ui/__init__.py,sha256=aRNE2pS50nFAX6y--rSGMNYwhz905g14gRd6g4BolYU,13
12
12
  abstractassistant/ui/chat_bubble.py,sha256=TE6zPtQ46I9grKGAb744wHqk4yO6-und3iif8_33XGk,11357
13
- abstractassistant/ui/history_dialog.py,sha256=25EVyf3-8Kaw1bZPTZe8G-uqw_KnP2t--OgAjsxC06w,18548
13
+ abstractassistant/ui/history_dialog.py,sha256=949l8fVgRpUfRGcoOVRutERVXrShYgpKkFJCxo2JG-4,19323
14
14
  abstractassistant/ui/provider_manager.py,sha256=9IM-BxIs6lUlk6cDCBi7oZFMXmn4CFMlxh0s-_vhzXY,8403
15
- abstractassistant/ui/qt_bubble.py,sha256=GO0IvM_04h9obRV6WbFKpJsoAwuftYkkljLtmw5XCYU,96483
15
+ abstractassistant/ui/qt_bubble.py,sha256=cBjViRyusWWEmX5bHz4k-W8mUFRY6RPOuUq5AyN7ciI,97030
16
16
  abstractassistant/ui/toast_manager.py,sha256=1aU4DPo-J45bC61gTEctHq98ZrHIFxRfZa_9Q8KF588,13721
17
17
  abstractassistant/ui/toast_window.py,sha256=BRSwEBlaND5LLipn1HOX0ISWxVH-zOHsYplFkiPaj_g,21727
18
18
  abstractassistant/ui/tts_state_manager.py,sha256=UF_zrfl9wf0hNHBGxevcoKxW5Dh7zXibUSVoSSjGP4o,10565
19
19
  abstractassistant/ui/ui_styles.py,sha256=FvE2CVUbHmHu1PKVTBBGyhbt781qh4WjLMrHviln39s,13120
20
20
  abstractassistant/utils/__init__.py,sha256=7Q3BxyXETkt3tm5trhuLTyL8PoECOK0QiK-0KUVAR2Q,16
21
- abstractassistant/utils/icon_generator.py,sha256=BLL0ULngPA3QGz_jJga491Fo3tnNi0fx5CcIzvLoVxg,16203
21
+ abstractassistant/utils/icon_generator.py,sha256=SWPgi1V6_8544Zbc2vAfFXAy15H35neyUGCYt2eKoic,16475
22
22
  abstractassistant/utils/markdown_renderer.py,sha256=u5tVIhulSwRYADiqJcZNoHhU8e6pJVgzrwZRd61Bov0,12585
23
- abstractassistant-0.3.0.dist-info/licenses/LICENSE,sha256=QUjFNAE-0yOkW9-Rle2axkpkt9H7xiZ2VbN-VeONhxc,1106
24
- abstractassistant-0.3.0.dist-info/METADATA,sha256=noWV-vlbNqvER5tPC8K2Ky1gl8V0qyGYdqpCkwX54sI,11320
25
- abstractassistant-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
- abstractassistant-0.3.0.dist-info/entry_points.txt,sha256=MIzeCh0XG6MbhIzBHtkdEjmjxYBsQrGFevq8Y1L8Jkc,118
27
- abstractassistant-0.3.0.dist-info/top_level.txt,sha256=oEcSXZAqbflTfZRfF4dogUq6TC1Nqyplq4JgC0CZnLI,34
28
- abstractassistant-0.3.0.dist-info/RECORD,,
23
+ abstractassistant-0.3.2.dist-info/licenses/LICENSE,sha256=QUjFNAE-0yOkW9-Rle2axkpkt9H7xiZ2VbN-VeONhxc,1106
24
+ abstractassistant-0.3.2.dist-info/METADATA,sha256=Z0vaLS5-e5Mm9urL8lLq7Rh-wvom7AtLdcCPdwSG-Uc,11320
25
+ abstractassistant-0.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
+ abstractassistant-0.3.2.dist-info/entry_points.txt,sha256=MIzeCh0XG6MbhIzBHtkdEjmjxYBsQrGFevq8Y1L8Jkc,118
27
+ abstractassistant-0.3.2.dist-info/top_level.txt,sha256=oEcSXZAqbflTfZRfF4dogUq6TC1Nqyplq4JgC0CZnLI,34
28
+ abstractassistant-0.3.2.dist-info/RECORD,,