chat-console 0.1.96.dev1__py3-none-any.whl → 0.1.991.dev1__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.
app/main.py CHANGED
@@ -19,7 +19,8 @@ from openai import OpenAI
19
19
  from app.models import Message, Conversation
20
20
  from app.database import ChatDatabase
21
21
  from app.config import CONFIG, OPENAI_API_KEY, ANTHROPIC_API_KEY, OLLAMA_BASE_URL
22
- from app.ui.chat_interface import MessageDisplay
22
+ # Import InputWithFocus as well
23
+ from app.ui.chat_interface import MessageDisplay, InputWithFocus
23
24
  from app.ui.model_selector import ModelSelector, StyleSelector
24
25
  from app.ui.chat_list import ChatList
25
26
  from app.api.base import BaseModelClient
@@ -114,10 +115,15 @@ class HistoryScreen(Screen):
114
115
  class SimpleChatApp(App): # Keep SimpleChatApp class definition
115
116
  """Simplified Chat CLI application.""" # Keep SimpleChatApp docstring
116
117
 
117
- TITLE = "Chat CLI" # Keep SimpleChatApp TITLE
118
+ TITLE = "Chat Console"
118
119
  SUB_TITLE = "AI Chat Interface" # Keep SimpleChatApp SUB_TITLE
119
120
  DARK = True # Keep SimpleChatApp DARK
120
121
 
122
+ # Ensure the log directory exists in a standard cache location
123
+ log_dir = os.path.expanduser("~/.cache/chat-cli")
124
+ os.makedirs(log_dir, exist_ok=True)
125
+ LOG_FILE = os.path.join(log_dir, "textual.log") # Use absolute path
126
+
121
127
  CSS = """ # Keep SimpleChatApp CSS start
122
128
  #main-content { # Keep SimpleChatApp CSS
123
129
  width: 100%;
@@ -240,15 +246,17 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
240
246
 
241
247
  BINDINGS = [ # Keep SimpleChatApp BINDINGS, ensure Enter is not globally bound for settings
242
248
  Binding("q", "quit", "Quit", show=True, key_display="q"),
249
+ # Removed priority=True - actions should only trigger when input is NOT focused
243
250
  Binding("n", "action_new_conversation", "New Chat", show=True, key_display="n"),
244
- Binding("c", "action_new_conversation", "New Chat", show=False, key_display="c"),
251
+ Binding("c", "action_new_conversation", "New Chat", show=False, key_display="c"), # Removed priority from alias
245
252
  Binding("escape", "escape", "Cancel / Stop", show=True, key_display="esc"), # Escape might close settings panel too
246
253
  Binding("ctrl+c", "quit", "Quit", show=False),
247
- Binding("h", "view_history", "History", show=True, key_display="h"),
248
- Binding("s", "settings", "Settings", show=True, key_display="s"),
254
+ Binding("h", "view_history", "History", show=True, key_display="h"), # Action method checks focus
255
+ Binding("s", "settings", "Settings", show=True, key_display="s"), # Action method checks focus
256
+ # Removed priority=True - action should only trigger when input is NOT focused
249
257
  Binding("t", "action_update_title", "Update Title", show=True, key_display="t"),
250
258
  ] # Keep SimpleChatApp BINDINGS end
251
-
259
+
252
260
  current_conversation = reactive(None) # Keep SimpleChatApp reactive var
253
261
  is_generating = reactive(False) # Keep SimpleChatApp reactive var
254
262
 
@@ -259,7 +267,8 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
259
267
  self.selected_model = CONFIG["default_model"] # Keep SimpleChatApp __init__
260
268
  self.selected_style = CONFIG["default_style"] # Keep SimpleChatApp __init__
261
269
  self.initial_text = initial_text # Keep SimpleChatApp __init__
262
-
270
+ # Removed self.input_widget instance variable
271
+
263
272
  def compose(self) -> ComposeResult: # Modify SimpleChatApp compose
264
273
  """Create the simplified application layout."""
265
274
  yield Header()
@@ -278,7 +287,8 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
278
287
 
279
288
  # Input area
280
289
  with Container(id="input-area"):
281
- yield Input(placeholder="Type your message here...", id="message-input")
290
+ # Use the custom InputWithFocus widget
291
+ yield InputWithFocus(placeholder="Type your message here...", id="message-input")
282
292
  # Removed Static widgets previously used for diagnosis
283
293
 
284
294
  # --- Add Settings Panel (hidden initially) ---
@@ -335,10 +345,12 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
335
345
  await self.action_send_message() # Keep SimpleChatApp on_mount
336
346
  else: # Keep SimpleChatApp on_mount
337
347
  # Focus the input if no initial text # Keep SimpleChatApp on_mount
348
+ # Removed assignment to self.input_widget
338
349
  self.query_one("#message-input").focus() # Keep SimpleChatApp on_mount
339
-
350
+
340
351
  async def create_new_conversation(self) -> None: # Keep SimpleChatApp create_new_conversation
341
352
  """Create a new chat conversation.""" # Keep SimpleChatApp create_new_conversation docstring
353
+ log("Entering create_new_conversation") # Added log
342
354
  # Create new conversation in database using selected model and style # Keep SimpleChatApp create_new_conversation
343
355
  model = self.selected_model # Keep SimpleChatApp create_new_conversation
344
356
  style = self.selected_style # Keep SimpleChatApp create_new_conversation
@@ -347,7 +359,9 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
347
359
  title = f"New conversation ({datetime.now().strftime('%Y-%m-%d %H:%M')})" # Keep SimpleChatApp create_new_conversation
348
360
 
349
361
  # Create conversation in database using the correct method # Keep SimpleChatApp create_new_conversation
362
+ log(f"Creating conversation with title: {title}, model: {model}, style: {style}") # Added log
350
363
  conversation_id = self.db.create_conversation(title, model, style) # Keep SimpleChatApp create_new_conversation
364
+ log(f"Database returned conversation_id: {conversation_id}") # Added log
351
365
 
352
366
  # Get the full conversation data # Keep SimpleChatApp create_new_conversation
353
367
  conversation_data = self.db.get_conversation(conversation_id) # Keep SimpleChatApp create_new_conversation
@@ -361,26 +375,42 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
361
375
 
362
376
  # Clear messages and update UI # Keep SimpleChatApp create_new_conversation
363
377
  self.messages = [] # Keep SimpleChatApp create_new_conversation
378
+ log("Finished updating messages UI in create_new_conversation") # Added log
364
379
  await self.update_messages_ui() # Keep SimpleChatApp create_new_conversation
365
-
380
+
366
381
  async def action_new_conversation(self) -> None: # Keep SimpleChatApp action_new_conversation
367
382
  """Handle the new conversation action.""" # Keep SimpleChatApp action_new_conversation docstring
368
- await self.create_new_conversation() # Keep SimpleChatApp action_new_conversation
383
+ log("--- ENTERING action_new_conversation ---") # Add entry log
369
384
 
385
+ # Check if the currently focused widget is the input widget
386
+ currently_focused = self.focused
387
+ if currently_focused and currently_focused.id == "message-input":
388
+ log("action_new_conversation skipped: input has focus")
389
+ return
390
+
391
+ log("action_new_conversation EXECUTING") # Add execution log
392
+ await self.create_new_conversation() # Keep SimpleChatApp action_new_conversation
393
+ log("action_new_conversation finished") # Added log
394
+
370
395
  def action_escape(self) -> None: # Modify SimpleChatApp action_escape
371
396
  """Handle escape key globally."""
397
+ log("action_escape triggered") # Added log
372
398
  settings_panel = self.query_one("#settings-panel")
399
+ log(f"Settings panel visible: {settings_panel.has_class('visible')}") # Added log
373
400
  if settings_panel.has_class("visible"):
401
+ log("Hiding settings panel") # Added log
374
402
  # If settings panel is visible, hide it
375
403
  settings_panel.remove_class("visible")
376
404
  self.query_one("#message-input").focus() # Focus input after closing settings
377
405
  elif self.is_generating:
406
+ log("Stopping generation") # Added log
378
407
  # Otherwise, stop generation if running
379
408
  self.is_generating = False # Keep SimpleChatApp action_escape
380
409
  self.notify("Generation stopped", severity="warning") # Keep SimpleChatApp action_escape
381
410
  loading = self.query_one("#loading-indicator") # Keep SimpleChatApp action_escape
382
411
  loading.add_class("hidden") # Keep SimpleChatApp action_escape
383
- # else: # Optional: Add other escape behavior for the main screen if desired # Keep SimpleChatApp action_escape comment
412
+ else: # Optional: Add other escape behavior for the main screen if desired # Keep SimpleChatApp action_escape comment
413
+ log("Escape pressed, but settings not visible and not generating.") # Added log
384
414
  # pass # Keep SimpleChatApp action_escape comment
385
415
 
386
416
  # Removed action_confirm_or_send - Enter is handled by Input submission # Keep SimpleChatApp comment
@@ -490,6 +520,7 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
490
520
  return # Keep SimpleChatApp generate_response
491
521
 
492
522
  self.is_generating = True # Keep SimpleChatApp generate_response
523
+ log(f"Setting is_generating to True") # Added log
493
524
  loading = self.query_one("#loading-indicator") # Keep SimpleChatApp generate_response
494
525
  loading.remove_class("hidden") # Keep SimpleChatApp generate_response
495
526
 
@@ -531,6 +562,7 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
531
562
 
532
563
  async def update_ui(content: str): # Keep SimpleChatApp generate_response
533
564
  if not self.is_generating: # Keep SimpleChatApp generate_response
565
+ log("update_ui called but is_generating is False, returning.") # Added log
534
566
  return # Keep SimpleChatApp generate_response
535
567
 
536
568
  async with update_lock: # Keep SimpleChatApp generate_response
@@ -550,7 +582,7 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
550
582
  # Force another refresh to ensure content is visible # Keep SimpleChatApp generate_response
551
583
  self.refresh(layout=True) # Keep SimpleChatApp generate_response
552
584
  except Exception as e: # Keep SimpleChatApp generate_response
553
- logger.error(f"Error updating UI: {str(e)}") # Keep SimpleChatApp generate_response
585
+ log.error(f"Error updating UI: {str(e)}") # Use log instead of logger
554
586
 
555
587
  # Generate the response with timeout and cleanup # Keep SimpleChatApp generate_response
556
588
  generation_task = None # Keep SimpleChatApp generate_response
@@ -558,6 +590,7 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
558
590
  # Create a task for the response generation # Keep SimpleChatApp generate_response
559
591
  generation_task = asyncio.create_task( # Keep SimpleChatApp generate_response
560
592
  generate_streaming_response( # Keep SimpleChatApp generate_response
593
+ self, # Pass the app instance
561
594
  api_messages, # Keep SimpleChatApp generate_response
562
595
  model, # Keep SimpleChatApp generate_response
563
596
  style, # Keep SimpleChatApp generate_response
@@ -571,6 +604,7 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
571
604
 
572
605
  # Save to database only if we got a complete response # Keep SimpleChatApp generate_response
573
606
  if self.is_generating and full_response: # Keep SimpleChatApp generate_response
607
+ log("Generation finished, saving full response to DB") # Added log
574
608
  self.db.add_message( # Keep SimpleChatApp generate_response
575
609
  self.current_conversation.id, # Keep SimpleChatApp generate_response
576
610
  "assistant", # Keep SimpleChatApp generate_response
@@ -579,9 +613,11 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
579
613
  # Force a final refresh # Keep SimpleChatApp generate_response
580
614
  self.refresh(layout=True) # Keep SimpleChatApp generate_response
581
615
  await asyncio.sleep(0.1) # Wait for UI to update # Keep SimpleChatApp generate_response
616
+ elif not full_response:
617
+ log("Generation finished but full_response is empty/None") # Added log
582
618
 
583
619
  except asyncio.TimeoutError: # Keep SimpleChatApp generate_response
584
- logger.error("Response generation timed out") # Keep SimpleChatApp generate_response
620
+ log.error("Response generation timed out") # Use log instead of logger
585
621
  error_msg = "Response generation timed out. The model may be busy or unresponsive. Please try again." # Keep SimpleChatApp generate_response
586
622
  self.notify(error_msg, severity="error") # Keep SimpleChatApp generate_response
587
623
 
@@ -596,22 +632,25 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
596
632
  # Ensure task is properly cancelled and cleaned up # Keep SimpleChatApp generate_response
597
633
  if generation_task: # Keep SimpleChatApp generate_response
598
634
  if not generation_task.done(): # Keep SimpleChatApp generate_response
635
+ log("Cancelling generation task") # Added log
599
636
  generation_task.cancel() # Keep SimpleChatApp generate_response
600
637
  try: # Keep SimpleChatApp generate_response
601
638
  await generation_task # Keep SimpleChatApp generate_response
602
639
  except (asyncio.CancelledError, Exception) as e: # Keep SimpleChatApp generate_response
603
- logger.error(f"Error cleaning up generation task: {str(e)}") # Keep SimpleChatApp generate_response
640
+ log.error(f"Error cleaning up generation task: {str(e)}") # Use log instead of logger
604
641
 
605
642
  # Force a final UI refresh # Keep SimpleChatApp generate_response
606
643
  self.refresh(layout=True) # Keep SimpleChatApp generate_response
607
644
 
608
645
  except Exception as e: # Keep SimpleChatApp generate_response
646
+ log.error(f"Exception during generate_response: {str(e)}") # Added log
609
647
  self.notify(f"Error generating response: {str(e)}", severity="error") # Keep SimpleChatApp generate_response
610
648
  # Add error message # Keep SimpleChatApp generate_response
611
649
  error_msg = f"Error generating response: {str(e)}" # Keep SimpleChatApp generate_response
612
650
  self.messages.append(Message(role="assistant", content=error_msg)) # Keep SimpleChatApp generate_response
613
651
  await self.update_messages_ui() # Keep SimpleChatApp generate_response
614
652
  finally: # Keep SimpleChatApp generate_response
653
+ log(f"Setting is_generating to False in finally block") # Added log
615
654
  self.is_generating = False # Keep SimpleChatApp generate_response
616
655
  loading = self.query_one("#loading-indicator") # Keep SimpleChatApp generate_response
617
656
  loading.add_class("hidden") # Keep SimpleChatApp generate_response
@@ -726,6 +765,16 @@ class SimpleChatApp(App): # Keep SimpleChatApp class definition
726
765
 
727
766
  async def action_update_title(self) -> None:
728
767
  """Allow users to manually change the conversation title"""
768
+ log("--- ENTERING action_update_title ---") # Add entry log
769
+
770
+ # Check focus using self.focused instead of has_focus
771
+ currently_focused = self.focused
772
+ if currently_focused and currently_focused.id == "message-input":
773
+ log("action_update_title skipped: input has focus")
774
+ return
775
+
776
+ log("action_update_title EXECUTING") # Add execution log
777
+
729
778
  if not self.current_conversation:
730
779
  self.notify("No active conversation", severity="warning")
731
780
  return
app/ui/chat_interface.py CHANGED
@@ -129,20 +129,23 @@ class MessageDisplay(RichLog):
129
129
 
130
130
  class InputWithFocus(Input):
131
131
  """Enhanced Input that better handles focus and maintains cursor position"""
132
-
132
+ # Reverted on_key to default Input behavior for 'n' and 't'
133
+ # Let the standard Input handle key presses when focused.
134
+ # We will rely on focus checks within the App's action methods.
135
+
136
+ # Keep custom handling only for Enter submission if needed,
137
+ # but standard Input might already do this. Let's simplify
138
+ # and remove the custom on_key entirely for now unless
133
139
  def on_key(self, event) -> None:
134
- """Custom key handling for input"""
135
- # Let control keys pass through
136
- if event.is_control:
137
- return super().on_key(event)
138
-
139
- # Handle Enter key
140
- if event.key == "enter":
141
- self.post_message(self.Submitted(self))
142
- return
143
-
144
- # Normal input handling for other keys
145
- super().on_key(event)
140
+ # Let global hotkeys 'n' and 't' pass through even when input has focus
141
+ # by simply *not* stopping the event here.
142
+ if event.key == "n" or event.key == "t":
143
+ # Do nothing, allow the event to bubble up to the app level bindings.
144
+ return # Explicitly return to prevent further processing in this method
145
+
146
+ # For all other keys, the event continues to be processed by the Input
147
+ # widget's internal handlers (like _on_key shown in the traceback)
148
+ # because we didn't stop it in this method.
146
149
 
147
150
  class ChatInterface(Container):
148
151
  """Main chat interface container"""
app/utils.py CHANGED
@@ -4,10 +4,14 @@ import time
4
4
  import asyncio
5
5
  import subprocess
6
6
  import logging
7
- from typing import Optional, Dict, Any, List
7
+ from typing import Optional, Dict, Any, List, TYPE_CHECKING
8
8
  from datetime import datetime
9
9
  from .config import CONFIG, save_config
10
10
 
11
+ # Import SimpleChatApp for type hinting only if TYPE_CHECKING is True
12
+ if TYPE_CHECKING:
13
+ from .main import SimpleChatApp
14
+
11
15
  # Set up logging
12
16
  logging.basicConfig(level=logging.INFO)
13
17
  logger = logging.getLogger(__name__)
@@ -74,7 +78,8 @@ async def generate_conversation_title(message: str, model: str, client: Any) ->
74
78
  logger.error(f"Failed to generate title after multiple retries. Last error: {last_error}")
75
79
  return f"Conversation ({datetime.now().strftime('%Y-%m-%d %H:%M')})"
76
80
 
77
- async def generate_streaming_response(messages: List[Dict], model: str, style: str, client: Any, callback: Any) -> str:
81
+ # Modified signature to accept app instance
82
+ async def generate_streaming_response(app: 'SimpleChatApp', messages: List[Dict], model: str, style: str, client: Any, callback: Any) -> str:
78
83
  """Generate a streaming response from the model"""
79
84
  logger.info(f"Starting streaming response with model: {model}")
80
85
  full_response = ""
@@ -84,6 +89,11 @@ async def generate_streaming_response(messages: List[Dict], model: str, style: s
84
89
 
85
90
  try:
86
91
  async for chunk in client.generate_stream(messages, model, style):
92
+ # Check if generation was cancelled by the app (e.g., via escape key)
93
+ if not app.is_generating:
94
+ logger.info("Generation cancelled by app flag.")
95
+ break # Exit the loop immediately
96
+
87
97
  if chunk: # Only process non-empty chunks
88
98
  buffer.append(chunk)
89
99
  current_time = time.time()
@@ -92,6 +102,10 @@ async def generate_streaming_response(messages: List[Dict], model: str, style: s
92
102
  if current_time - last_update >= update_interval or len(''.join(buffer)) > 100:
93
103
  new_content = ''.join(buffer)
94
104
  full_response += new_content
105
+ # Check again before calling callback, in case it was cancelled during chunk processing
106
+ if not app.is_generating:
107
+ logger.info("Generation cancelled before UI update.")
108
+ break
95
109
  await callback(full_response)
96
110
  buffer = []
97
111
  last_update = current_time
@@ -99,16 +113,22 @@ async def generate_streaming_response(messages: List[Dict], model: str, style: s
99
113
  # Small delay to let UI catch up
100
114
  await asyncio.sleep(0.05)
101
115
 
102
- # Send any remaining content
103
- if buffer:
116
+ # Send any remaining content if generation wasn't cancelled
117
+ if buffer and app.is_generating:
104
118
  new_content = ''.join(buffer)
105
119
  full_response += new_content
106
120
  await callback(full_response)
107
121
 
108
- logger.info("Streaming response completed")
122
+ if app.is_generating:
123
+ logger.info("Streaming response completed normally.")
124
+ else:
125
+ logger.info("Streaming response loop exited due to cancellation.")
126
+
109
127
  return full_response
110
128
  except Exception as e:
111
129
  logger.error(f"Error in streaming response: {str(e)}")
130
+ # Ensure the app knows generation stopped on error
131
+ app.is_generating = False
112
132
  raise
113
133
 
114
134
  def ensure_ollama_running() -> bool:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chat-console
3
- Version: 0.1.96.dev1
3
+ Version: 0.1.991.dev1
4
4
  Summary: A command-line interface for chatting with LLMs, storing chats and (future) rag interactions
5
5
  Home-page: https://github.com/wazacraftrfid/chat-console
6
6
  Author: Johnathan Greenaway
@@ -1,23 +1,23 @@
1
1
  app/__init__.py,sha256=OeqboIrx_Kjea0CY9Be8nLI-No1YWQfqbWIp-4lMOOI,131
2
2
  app/config.py,sha256=sKNp6Za4ZfW-CZBOvEv0TncAS77AnKi86hTM51C4KQ4,5227
3
3
  app/database.py,sha256=nt8CVuDpy6zw8mOYqDcfUmNw611t7Ln7pz22M0b6-MI,9967
4
- app/main.py,sha256=SfeSORMICQR5GPwniN-Hg0TH9xvhmWHvkhTdyxjbK3k,43450
4
+ app/main.py,sha256=PepaAw5akZkWQDeq-BNRVhXWNqsztu9-Tgsz9LuIBTg,46275
5
5
  app/models.py,sha256=4-y9Lytay2exWPFi0FDlVeRL3K2-I7E-jBqNzTfokqY,2644
6
- app/utils.py,sha256=VzsdBvuj8zk7HsLlBjIvq6jvU1G2lSEE1Ml6_sbYs1I,7432
6
+ app/utils.py,sha256=AgmLrmyikt1Y7KturNmZVK2eC6de-RfRadVbp3HmUAg,8434
7
7
  app/api/__init__.py,sha256=A8UL84ldYlv8l7O-yKzraVFcfww86SgWfpl4p7R03-w,62
8
8
  app/api/anthropic.py,sha256=x5PmBXEKe_ow2NWk8XdqSPR0hLOdCc_ypY5QAySeA78,4234
9
9
  app/api/base.py,sha256=-6RSxSpqe-OMwkaq1wVWbu3pVkte-ZYy8rmdvt-Qh48,3953
10
10
  app/api/ollama.py,sha256=zFZ3g2sYncvMgcvx92jTCLkigIaDvTuhILcLiCrwisc,11640
11
11
  app/api/openai.py,sha256=1fYgFXXL6yj_7lQ893Yj28RYG4M8d6gt_q1gzhhjcig,3641
12
12
  app/ui/__init__.py,sha256=RndfbQ1Tv47qdSiuQzvWP96lPS547SDaGE-BgOtiP_w,55
13
- app/ui/chat_interface.py,sha256=4ahB7IpqL3hLzVPsfN6E4uC833_gMvRSzjSVfdjHGUY,13082
13
+ app/ui/chat_interface.py,sha256=VwmVvltxS9l18DI9U7kL43t8kSPPNsrkkrrUSoGu16Q,13623
14
14
  app/ui/chat_list.py,sha256=WQTYVNSSXlx_gQal3YqILZZKL9UiTjmNMIDX2I9pAMM,11205
15
15
  app/ui/model_selector.py,sha256=Aj1irAs9DQMn8wfcPsFZGxWmx0JTzHjSe7pVdDMwqTQ,13182
16
16
  app/ui/search.py,sha256=b-m14kG3ovqW1-i0qDQ8KnAqFJbi5b1FLM9dOnbTyIs,9763
17
17
  app/ui/styles.py,sha256=04AhPuLrOd2yenfRySFRestPeuTPeMLzhmMB67NdGvw,5615
18
- chat_console-0.1.96.dev1.dist-info/licenses/LICENSE,sha256=srHZ3fvcAuZY1LHxE7P6XWju2njRCHyK6h_ftEbzxSE,1057
19
- chat_console-0.1.96.dev1.dist-info/METADATA,sha256=EVvIxf_H7acsAEoSRl2Jw-LeIPdwJVLLS6ca7KcyOXY,2927
20
- chat_console-0.1.96.dev1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
21
- chat_console-0.1.96.dev1.dist-info/entry_points.txt,sha256=kkVdEc22U9PAi2AeruoKklfkng_a_aHAP6VRVwrAD7c,67
22
- chat_console-0.1.96.dev1.dist-info/top_level.txt,sha256=io9g7LCbfmTG1SFKgEOGXmCFB9uMP2H5lerm0HiHWQE,4
23
- chat_console-0.1.96.dev1.dist-info/RECORD,,
18
+ chat_console-0.1.991.dev1.dist-info/licenses/LICENSE,sha256=srHZ3fvcAuZY1LHxE7P6XWju2njRCHyK6h_ftEbzxSE,1057
19
+ chat_console-0.1.991.dev1.dist-info/METADATA,sha256=1eRmKQXkPFNZT4f54lotKMLPMsmJP4gSLecZZN82VuY,2928
20
+ chat_console-0.1.991.dev1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
21
+ chat_console-0.1.991.dev1.dist-info/entry_points.txt,sha256=kkVdEc22U9PAi2AeruoKklfkng_a_aHAP6VRVwrAD7c,67
22
+ chat_console-0.1.991.dev1.dist-info/top_level.txt,sha256=io9g7LCbfmTG1SFKgEOGXmCFB9uMP2H5lerm0HiHWQE,4
23
+ chat_console-0.1.991.dev1.dist-info/RECORD,,