@@ -182,13 +182,13 @@ def __init__(
182
182
hass .config .path (".storage" ),
183
183
"ha_text_ai_history"
184
184
)
185
- hass .async_create_task (self ._create_history_dir ())
186
185
187
- hass .async_create_task (self ._check_history_directory ())
188
-
189
- hass .async_create_task (self ._migrate_history_from_txt_to_json ())
190
-
191
- hass .async_create_task (self ._initialize_metrics ())
186
+ # Initialize all async tasks in proper order
187
+ self .hass .async_create_task (self ._create_history_dir ())
188
+ self .hass .async_create_task (self ._check_history_directory ())
189
+ self .hass .async_create_task (self ._initialize_metrics ())
190
+ self .hass .async_create_task (self .async_initialize_history_file ())
191
+ self .hass .async_create_task (self ._migrate_history_from_txt_to_json ())
192
192
193
193
# History file path using instance name
194
194
self ._history_file = os .path .join (
@@ -273,18 +273,17 @@ async def _file_exists(self, path: str) -> bool:
273
273
_LOGGER .error (f"Error checking file existence for { path } : { e } " )
274
274
return False
275
275
276
- async def _create_history_dir (self ):
276
+ async def _create_history_dir (self ) -> None :
277
277
"""
278
278
Asynchronously create history directory.
279
-
280
- Creates the directory for storing history files
281
- without blocking the event loop.
282
279
"""
283
280
try :
284
- await self .hass .async_add_executor_job (
285
- lambda : os .makedirs (self ._history_dir , exist_ok = True )
286
- )
287
- _LOGGER .debug (f"Directory creation details: exist_ok=True" )
281
+ def mkdir_sync ():
282
+ os .makedirs (self ._history_dir , exist_ok = True )
283
+
284
+ await self .hass .async_add_executor_job (mkdir_sync )
285
+ _LOGGER .debug (f"History directory created/verified: { self ._history_dir } " )
286
+
288
287
except PermissionError :
289
288
_LOGGER .error (f"Permission denied when creating history directory: { self ._history_dir } " )
290
289
raise
@@ -406,25 +405,21 @@ async def _handle_error(self, error: Exception) -> None:
406
405
async def async_initialize_history_file (self ) -> None :
407
406
"""
408
407
Asynchronously initialize history file.
409
-
410
- Creates the file and writes an initialization timestamp
411
- without blocking the event loop using Home Assistant's executor.
412
408
"""
413
409
try :
414
- await self .hass .async_add_executor_job (self ._sync_initialize_history_file )
415
- except Exception as e :
416
- _LOGGER .error (f"Could not initialize history file: { e } " )
417
- _LOGGER .debug (traceback .format_exc ())
410
+ # Ensure directory exists first
411
+ await self ._create_history_dir ()
418
412
419
- async def _sync_initialize_history_file (self ) -> None :
420
- try :
413
+ # Initialize file
421
414
if not await self ._file_exists (self ._history_file ):
422
- def write_empty_history ():
423
- with open (self ._history_file , 'w' ) as f :
424
- json .dump ([], f )
425
- await self .hass .async_add_executor_job (write_empty_history )
415
+ async with AsyncFileHandler (self ._history_file , 'w' ) as f :
416
+ await f .write (json .dumps ([]))
417
+
418
+ _LOGGER .debug (f"History file initialized: { self ._history_file } " )
419
+
426
420
except Exception as e :
427
- _LOGGER .error (f"History file initialization failed: { e } " )
421
+ _LOGGER .error (f"Could not initialize history file: { e } " )
422
+ _LOGGER .debug (traceback .format_exc ())
428
423
429
424
# Size check to _update_history method
430
425
async def _update_history (self , question : str , response : dict ) -> None :
@@ -565,7 +560,10 @@ async def _check_history_directory(self) -> None:
565
560
Asynchronously check history directory permissions and writability.
566
561
"""
567
562
try :
568
- # Test write permission in a separate thread
563
+ # First ensure directory exists
564
+ await self ._create_history_dir ()
565
+
566
+ # Then test write permission in a separate thread
569
567
test_file_path = os .path .join (self ._history_dir , ".write_test" )
570
568
await self .hass .async_add_executor_job (self ._sync_test_directory_write , test_file_path )
571
569
@@ -754,7 +752,7 @@ def _get_safe_initial_state(self) -> Dict[str, Any]:
754
752
"normalized_name" : self .normalized_name ,
755
753
}
756
754
757
- def _calculate_context_tokens (self , messages : List [Dict [str , str ]]) -> int :
755
+ def _calculate_context_tokens (self , messages : List [Dict [str , str ]], model : Optional [ str ] = None ) -> int :
758
756
total_tokens = 0
759
757
760
758
# Compile regular expressions for performance
@@ -865,7 +863,8 @@ async def async_process_question(
865
863
context_tokens = self ._calculate_context_tokens (
866
864
[{"content" : entry ["question" ]} for entry in context_history ] +
867
865
[{"content" : entry ["response" ]} for entry in context_history ] +
868
- [{"content" : question }]
866
+ [{"content" : question }],
867
+ temp_model
869
868
)
870
869
871
870
# Dynamic token allocation
@@ -885,7 +884,8 @@ async def async_process_question(
885
884
context_tokens = self ._calculate_context_tokens (
886
885
[{"content" : entry ["question" ]} for entry in context_history ] +
887
886
[{"content" : entry ["response" ]} for entry in context_history ] +
888
- [{"content" : question }]
887
+ [{"content" : question }],
888
+ temp_model
889
889
)
890
890
891
891
# Rebuild messages with trimmed context
0 commit comments