ara-cli 0.1.9.76__py3-none-any.whl → 0.1.9.78__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.

Potentially problematic release.


This version of ara-cli might be problematic. Click here for more details.

tests/test_chat.py CHANGED
@@ -185,7 +185,7 @@ def test_disable_commands(temp_chat_file):
185
185
  (["This is a line.", "Another line here.", "Yet another line."], None),
186
186
  (["This is a line.", "# ara prompt:", "Another line here."], "# ara prompt:"),
187
187
  (["This is a line.", "# ara prompt:", "Another line here.", "# ara response:"], "# ara response:"),
188
- (["This is a line.", " # ara prompt: ", "Another line here.", " # ara response: "], "# ara response:"),
188
+ (["This is a line.", " # ara prompt: ", "Another line here.", " # ara response: "], "# ara response:"),
189
189
  (["# ara prompt:", "# ara response:"], "# ara response:"),
190
190
  (["# ara response:", "# ara prompt:", "# ara prompt:", "# ara response:"], "# ara response:"),
191
191
  ([], None)
@@ -233,8 +233,8 @@ def test_start(temp_chat_file):
233
233
  (["This is a line.\n", "# ara prompt:\n", "Another line here.\n", "# ara response:\n"],
234
234
  ["This is a line.\n", "# ara prompt:\n", "Another line here.\n", "# ara response:\n", "\n", "# ara prompt:"]),
235
235
 
236
- (["This is a line.\n", " # ara prompt: \n", "Another line here.\n", " # ara response: \n"],
237
- ["This is a line.\n", " # ara prompt: \n", "Another line here.\n", " # ara response: \n", "\n", "# ara prompt:"]),
236
+ (["This is a line.\n", " # ara prompt: \n", "Another line here.\n", " # ara response: \n"],
237
+ ["This is a line.\n", " # ara prompt: \n", "Another line here.\n", " # ara response: \n", "\n", "# ara prompt:"]),
238
238
 
239
239
  (["# ara prompt:\n", "# ara response:\n"],
240
240
  ["# ara prompt:\n", "# ara response:\n", "\n", "# ara prompt:"]),
@@ -257,7 +257,7 @@ def test_add_prompt_tag_if_needed(temp_chat_file, initial_content, expected_cont
257
257
 
258
258
 
259
259
  @pytest.mark.parametrize("lines, expected", [
260
- (["\n", " ", "# ara prompt:", "Another line here.", " \n"], "Another line here."),
260
+ (["\n", " ", "# ara prompt:", "Another line here.", " \n"], "Another line here."),
261
261
  (["This is a line.", "Another line here.", " \n", "\n"], "Another line here."),
262
262
  (["\n", " \n", " \n"], ""),
263
263
  (["This is a line.", "Another line here.", "# ara response:", " \n"], "# ara response:"),
@@ -270,7 +270,7 @@ def test_get_last_non_empty_line(lines, expected, temp_chat_file):
270
270
  assert Chat.get_last_non_empty_line(Chat, file) == expected
271
271
 
272
272
  @pytest.mark.parametrize("lines, expected", [
273
- (["\n", " ", "# ara prompt:", "Another line here.", " \n"], ""),
273
+ (["\n", " ", "# ara prompt:", "Another line here.", " \n"], ""),
274
274
  (["This is a line.", "Another line here."], "Another line here."),
275
275
  (["\n", " \n", " \n"], ""),
276
276
  (["This is a line.", "Another line here.", "# ara response:", " \n"], ""),
@@ -290,7 +290,7 @@ def test_get_last_line(lines, expected, temp_chat_file):
290
290
  (["Text with image", "(data:image/png;base64,abc123)"],
291
291
  "Text with image",
292
292
  [{"type": "image_url", "image_url": {"url": "data:image/png;base64,abc123"}}]),
293
- (["Just text", "Another (data:image/png;base64,xyz789) image"],
293
+ (["Just text", "Another (data:image/png;base64,xyz789) image"],
294
294
  "Just text",
295
295
  [{"type": "image_url", "image_url": {"url": "data:image/png;base64,xyz789"}}]),
296
296
  (["No images here at all"], "No images here at all", []),
@@ -392,7 +392,7 @@ def test_save_message(temp_chat_file, role, message, initial_content, expected_c
392
392
  def test_resend_message(temp_chat_file, initial_content, expected_content):
393
393
  temp_chat_file.writelines(initial_content)
394
394
  temp_chat_file.flush()
395
-
395
+
396
396
  mock_config = get_default_config()
397
397
  with patch('ara_cli.prompt_handler.ConfigManager.get_config', return_value=mock_config):
398
398
  chat = Chat(temp_chat_file.name, reset=False)
@@ -456,7 +456,7 @@ def test_determine_file_path(temp_chat_file):
456
456
  ]
457
457
 
458
458
  with patch('os.path.exists') as mock_exists, \
459
- patch('os.path.dirname', return_value="current_directory") as mock_dirname:
459
+ patch('os.path.dirname', return_value="current_directory") as mock_dirname:
460
460
 
461
461
  for file_name, exists_in_current, exists_elsewhere, expected_path in test_cases:
462
462
  mock_exists.side_effect = [exists_in_current, exists_elsewhere]
@@ -501,9 +501,9 @@ def test_load_text_file_file_not_found(temp_chat_file):
501
501
  with patch("builtins.open", mock_open()) as mock_file:
502
502
  result = chat.load_text_file("nonexistent.txt")
503
503
 
504
- assert result is False
504
+ assert result is False
505
505
 
506
- mock_file.assert_not_called()
506
+ mock_file.assert_not_called()
507
507
 
508
508
 
509
509
  @pytest.mark.parametrize("file_name, mime_type, file_content, expected, path_exists", [
@@ -516,7 +516,6 @@ def test_load_binary_file(temp_chat_file, file_name, mime_type, file_content, ex
516
516
  with patch('ara_cli.prompt_handler.ConfigManager.get_config', return_value=mock_config):
517
517
  chat = Chat(temp_chat_file.name, reset=False)
518
518
 
519
- # Mock open to handle both read and write operations
520
519
  mock_file = mock_open(read_data=file_content)
521
520
 
522
521
  with patch('builtins.open', mock_file) as mocked_open, \
@@ -535,36 +534,112 @@ def test_load_binary_file(temp_chat_file, file_name, mime_type, file_content, ex
535
534
  assert result is False
536
535
 
537
536
 
538
- @pytest.mark.parametrize("file_name, is_binary", [
539
- ("image.png", True), # Binary file
540
- ("document.txt", False) # Text file
537
+ @pytest.mark.parametrize("file_name, loader_path, mock_setup, expected_content", [
538
+ (
539
+ "test.docx",
540
+ "docx.Document",
541
+ lambda mock: setattr(mock.return_value, 'paragraphs', [MagicMock(text="Docx content")]),
542
+ "Docx content"
543
+ ),
544
+ pytest.param(
545
+ "test.pdf",
546
+ "pymupdf4llm.to_markdown",
547
+ lambda mock: setattr(mock, 'return_value', "PDF content"),
548
+ "PDF content",
549
+ marks=pytest.mark.filterwarnings("ignore::DeprecationWarning")
550
+ ),
551
+ pytest.param(
552
+ "test.odt",
553
+ "pymupdf4llm.to_markdown",
554
+ lambda mock: setattr(mock, 'return_value', "ODT content"),
555
+ "ODT content",
556
+ marks=pytest.mark.filterwarnings("ignore::DeprecationWarning")
557
+ ),
541
558
  ])
542
- def test_load_file(temp_chat_file, file_name, is_binary):
559
+ def test_load_document_file(temp_chat_file, file_name, loader_path, mock_setup, expected_content):
560
+ mock_config = get_default_config()
561
+ with patch('ara_cli.prompt_handler.ConfigManager.get_config', return_value=mock_config):
562
+ chat = Chat(temp_chat_file.name, reset=False)
563
+
564
+ with patch(loader_path, create=True) as mock_loader, \
565
+ patch("builtins.open", mock_open()) as mock_chat_open:
566
+
567
+ mock_setup(mock_loader)
568
+
569
+ with patch.object(chat, 'determine_file_path', return_value=file_name):
570
+ result = chat.load_document_file(file_name, prefix="Prefix-", suffix="-Suffix", block_delimiter="```")
571
+
572
+ assert result is True
573
+
574
+ if loader_path == "pymupdf4llm.to_markdown":
575
+ mock_loader.assert_called_once_with(file_name, write_images=False)
576
+ else:
577
+ mock_loader.assert_called_once_with(file_name)
578
+
579
+ expected_write = f"Prefix-```\n{expected_content}\n```-Suffix\n"
580
+ mock_chat_open.assert_called_with(chat.chat_name, 'a', encoding='utf-8')
581
+ mock_chat_open().write.assert_called_once_with(expected_write)
582
+
583
+
584
+ def test_load_document_file_unsupported(temp_chat_file, capsys):
585
+ mock_config = get_default_config()
586
+ with patch('ara_cli.prompt_handler.ConfigManager.get_config', return_value=mock_config):
587
+ chat = Chat(temp_chat_file.name, reset=False)
588
+
589
+ unsupported_file = "test.txt"
590
+ with patch.object(chat, 'determine_file_path', return_value=unsupported_file):
591
+ result = chat.load_document_file(unsupported_file)
592
+
593
+ assert result is False
594
+ captured = capsys.readouterr()
595
+ assert "Unsupported document type." in captured.out
596
+
597
+
598
+ @pytest.mark.parametrize("file_name, file_type, mime_type", [
599
+ ("image.png", "binary", "image/png"),
600
+ ("document.txt", "text", None),
601
+ ("document.docx", "document", None),
602
+ ("document.pdf", "document", None),
603
+ ("archive.zip", "text", None),
604
+ ])
605
+ def test_load_file(temp_chat_file, file_name, file_type, mime_type):
543
606
  mock_config = get_default_config()
544
607
  with patch('ara_cli.prompt_handler.ConfigManager.get_config', return_value=mock_config):
545
608
  chat = Chat(temp_chat_file.name, reset=False)
546
609
 
547
610
  with patch.object(chat, 'load_binary_file', return_value=True) as mock_load_binary, \
548
- patch.object(chat, 'load_text_file', return_value=True) as mock_load_text:
611
+ patch.object(chat, 'load_text_file', return_value=True) as mock_load_text, \
612
+ patch.object(chat, 'load_document_file', return_value=True) as mock_load_document:
549
613
 
550
- chat.load_file(file_name=file_name)
614
+ chat.load_file(file_name=file_name, prefix="p-", suffix="-s", block_delimiter="b")
551
615
 
552
- if is_binary:
616
+ if file_type == "binary":
553
617
  mock_load_binary.assert_called_once_with(
554
618
  file_name=file_name,
555
- mime_type='image/png',
556
- prefix="",
557
- suffix=""
619
+ mime_type=mime_type,
620
+ prefix="p-",
621
+ suffix="-s"
558
622
  )
559
623
  mock_load_text.assert_not_called()
624
+ mock_load_document.assert_not_called()
625
+ elif file_type == "document":
626
+ mock_load_binary.assert_not_called()
627
+ mock_load_text.assert_not_called()
628
+ mock_load_document.assert_called_once_with(
629
+ file_name=file_name,
630
+ prefix="p-",
631
+ suffix="-s",
632
+ block_delimiter="b"
633
+ )
560
634
  else:
635
+ mock_load_binary.assert_not_called()
561
636
  mock_load_text.assert_called_once_with(
562
637
  file_name=file_name,
563
- prefix="",
564
- suffix="",
565
- block_delimiter=""
638
+ prefix="p-",
639
+ suffix="-s",
640
+ block_delimiter="b"
566
641
  )
567
- mock_load_binary.assert_not_called()
642
+ mock_load_document.assert_not_called()
568
643
 
569
644
 
570
645
  @pytest.mark.parametrize("files, pattern, user_input, expected_output, expected_file", [
@@ -788,6 +863,71 @@ def test_complete_LOAD(monkeypatch, temp_chat_file, text, line, begidx, endidx,
788
863
  assert completions == matching_files
789
864
 
790
865
 
866
+ @pytest.mark.parametrize("file_name, is_image, expected_mime", [
867
+ ("test.png", True, "image/png"),
868
+ ("test.jpg", True, "image/jpeg"),
869
+ ("test.jpeg", True, "image/jpeg"),
870
+ ("test.txt", False, None)
871
+ ])
872
+ def test_load_image(capsys, temp_chat_file, file_name, is_image, expected_mime):
873
+ mock_config = get_default_config()
874
+ with patch('ara_cli.prompt_handler.ConfigManager.get_config', return_value=mock_config):
875
+ chat = Chat(temp_chat_file.name, reset=False)
876
+
877
+ with patch.object(chat, 'load_binary_file', return_value=True) as mock_load_binary:
878
+ chat.load_image(file_name=file_name, prefix="p-", suffix="-s")
879
+
880
+ if is_image:
881
+ mock_load_binary.assert_called_once_with(
882
+ file_name=file_name,
883
+ mime_type=expected_mime,
884
+ prefix="p-",
885
+ suffix="-s"
886
+ )
887
+ else:
888
+ mock_load_binary.assert_not_called()
889
+ captured = capsys.readouterr()
890
+ assert f"File {file_name} not recognized as image, could not load" in captured.out
891
+
892
+
893
+ def test_do_LOAD_DOCUMENT(capsys, temp_chat_file):
894
+ mock_config = get_default_config()
895
+ with patch('ara_cli.prompt_handler.ConfigManager.get_config', return_value=mock_config):
896
+ chat = Chat(temp_chat_file.name, reset=False)
897
+
898
+ doc_file = "test.docx"
899
+ with patch.object(chat, 'find_matching_files_to_load', return_value=[doc_file]) as mock_find, \
900
+ patch.object(chat, 'load_document_file', return_value=True) as mock_load, \
901
+ patch.object(chat, 'add_prompt_tag_if_needed') as mock_add_tag:
902
+
903
+ chat.do_LOAD_DOCUMENT(doc_file)
904
+
905
+ mock_find.assert_called_once_with(doc_file)
906
+ mock_add_tag.assert_called_once_with(chat.chat_name)
907
+ mock_load.assert_called_once_with(doc_file, prefix=f"\nFile: {doc_file}\n")
908
+ captured = capsys.readouterr()
909
+ assert f"Loaded document file {doc_file}" in captured.out
910
+
911
+
912
+ def test_do_LOAD_IMAGE(capsys, temp_chat_file):
913
+ mock_config = get_default_config()
914
+ with patch('ara_cli.prompt_handler.ConfigManager.get_config', return_value=mock_config):
915
+ chat = Chat(temp_chat_file.name, reset=False)
916
+
917
+ image_file = "test.png"
918
+ with patch.object(chat, 'find_matching_files_to_load', return_value=[image_file]) as mock_find, \
919
+ patch.object(chat, 'load_image', return_value=True) as mock_load, \
920
+ patch.object(chat, 'add_prompt_tag_if_needed') as mock_add_tag:
921
+
922
+ chat.do_LOAD_IMAGE(image_file)
923
+
924
+ mock_find.assert_called_once_with(image_file)
925
+ mock_add_tag.assert_called_once_with(chat.chat_name)
926
+ mock_load.assert_called_once_with(image_file, prefix=f"\nFile: {image_file}\n")
927
+ captured = capsys.readouterr()
928
+ assert f"Loaded image file {image_file}" in captured.out
929
+
930
+
791
931
  @pytest.mark.parametrize("input_chat_name, expected_chat_name", [
792
932
  ("", "What should be the new chat name? "),
793
933
  ("new_chat", "new_chat_chat.md"),
@@ -796,13 +936,13 @@ def test_complete_LOAD(monkeypatch, temp_chat_file, text, line, begidx, endidx,
796
936
  def test_do_new(monkeypatch, temp_chat_file, input_chat_name, expected_chat_name):
797
937
  def mock_input(prompt):
798
938
  return "input_chat_name"
799
-
939
+
800
940
  monkeypatch.setattr('builtins.input', mock_input)
801
941
 
802
942
  mock_config = get_default_config()
803
943
  with patch('ara_cli.prompt_handler.ConfigManager.get_config', return_value=mock_config):
804
944
  chat = Chat(temp_chat_file.name, reset=False)
805
-
945
+
806
946
  with patch.object(Chat, '__init__', return_value=None) as mock_init:
807
947
  chat.do_NEW(input_chat_name)
808
948
  if input_chat_name == "":
@@ -1057,10 +1197,9 @@ def test_do_SEND(temp_chat_file):
1057
1197
  ("AnotherTemplate", MagicMock(serialize=MagicMock(return_value="other_content")), "other_content", "Loaded AnotherTemplate artefact template\n"),
1058
1198
  ])
1059
1199
  def test_do_LOAD_TEMPLATE_success(temp_chat_file, template_name, artefact_obj, expected_write, expected_print, capsys):
1060
- mock_config = MagicMock() # or use get_default_config() if needed
1200
+ mock_config = MagicMock()
1061
1201
  with patch('ara_cli.prompt_handler.ConfigManager.get_config', return_value=mock_config):
1062
1202
  chat = Chat(temp_chat_file.name, reset=False)
1063
- # Patch the artefact loader to return artefact_obj
1064
1203
  with patch('ara_cli.artefact_models.artefact_templates.template_artefact_of_type', return_value=artefact_obj) as mock_template_loader, \
1065
1204
  patch.object(chat, 'add_prompt_tag_if_needed') as mock_add_prompt_tag, \
1066
1205
  patch("builtins.open", mock_open()) as mock_file:
@@ -1087,4 +1226,4 @@ def test_do_LOAD_TEMPLATE_missing_artefact(temp_chat_file, template_name):
1087
1226
  chat.do_LOAD_TEMPLATE(template_name)
1088
1227
  mock_template_loader.assert_called_once_with(template_name)
1089
1228
  mock_add_prompt_tag.assert_not_called()
1090
- mock_file.assert_not_called()
1229
+ mock_file.assert_not_called()
@@ -1,16 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: ara_cli
3
- Version: 0.1.9.76
4
- Requires-Dist: litellm
5
- Requires-Dist: llama-index
6
- Requires-Dist: llama-index-llms-openai
7
- Requires-Dist: llama-index-retrievers-bm25
8
- Requires-Dist: openai
9
- Requires-Dist: markdown-it-py
10
- Requires-Dist: json-repair
11
- Requires-Dist: argparse
12
- Requires-Dist: argcomplete
13
- Requires-Dist: cmd2>=2.5
14
- Requires-Dist: pydantic
15
- Requires-Dist: pydantic_ai
16
- Dynamic: requires-dist