janito 1.7.0__py3-none-any.whl → 1.8.0__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.
- janito/__init__.py +1 -1
- janito/agent/config.py +1 -1
- janito/agent/config_defaults.py +2 -2
- janito/agent/conversation.py +70 -27
- janito/agent/conversation_api.py +104 -4
- janito/agent/conversation_exceptions.py +6 -0
- janito/agent/conversation_tool_calls.py +17 -3
- janito/agent/event.py +24 -0
- janito/agent/event_dispatcher.py +24 -0
- janito/agent/event_handler_protocol.py +5 -0
- janito/agent/event_system.py +15 -0
- janito/agent/message_handler.py +4 -1
- janito/agent/message_handler_protocol.py +5 -0
- janito/agent/openai_client.py +5 -8
- janito/agent/openai_schema_generator.py +23 -4
- janito/agent/profile_manager.py +15 -83
- janito/agent/queued_message_handler.py +22 -3
- janito/agent/rich_message_handler.py +66 -72
- janito/agent/templates/profiles/system_prompt_template_base.txt.j2 +14 -0
- janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2 +13 -0
- janito/agent/test_handler_protocols.py +47 -0
- janito/agent/tests/__init__.py +1 -0
- janito/agent/tool_base.py +1 -1
- janito/agent/tool_executor.py +109 -0
- janito/agent/tool_registry.py +3 -75
- janito/agent/tool_use_tracker.py +46 -0
- janito/agent/tools/__init__.py +8 -9
- janito/agent/tools/ask_user.py +19 -11
- janito/agent/tools/create_directory.py +43 -28
- janito/agent/tools/create_file.py +60 -29
- janito/agent/tools/dir_walk_utils.py +16 -0
- janito/agent/tools/fetch_url.py +10 -11
- janito/agent/tools/find_files.py +49 -32
- janito/agent/tools/get_lines.py +54 -18
- janito/agent/tools/memory.py +32 -52
- janito/agent/tools/move_file.py +72 -23
- janito/agent/tools/outline_file/__init__.py +85 -0
- janito/agent/tools/outline_file/formatting.py +20 -0
- janito/agent/tools/outline_file/markdown_outline.py +14 -0
- janito/agent/tools/outline_file/python_outline.py +71 -0
- janito/agent/tools/present_choices.py +62 -0
- janito/agent/tools/present_choices_test.py +18 -0
- janito/agent/tools/remove_directory.py +31 -26
- janito/agent/tools/remove_file.py +31 -13
- janito/agent/tools/replace_text_in_file.py +135 -36
- janito/agent/tools/run_bash_command.py +47 -50
- janito/agent/tools/run_powershell_command.py +52 -36
- janito/agent/tools/run_python_command.py +49 -29
- janito/agent/tools/search_outline.py +17 -0
- janito/agent/tools/search_text.py +208 -0
- janito/agent/tools/tools_utils.py +47 -4
- janito/agent/tools/utils.py +14 -15
- janito/agent/tools/validate_file_syntax.py +163 -0
- janito/cli/arg_parser.py +36 -4
- janito/cli/logging_setup.py +7 -2
- janito/cli/main.py +96 -2
- janito/cli/runner/_termweb_log_utils.py +17 -0
- janito/cli/runner/cli_main.py +119 -77
- janito/cli/runner/config.py +2 -2
- janito/cli/termweb_starter.py +73 -0
- janito/cli_chat_shell/chat_loop.py +42 -7
- janito/cli_chat_shell/chat_state.py +1 -1
- janito/cli_chat_shell/chat_ui.py +0 -1
- janito/cli_chat_shell/commands/__init__.py +15 -6
- janito/cli_chat_shell/commands/{history_reset.py → history_start.py} +13 -5
- janito/cli_chat_shell/commands/lang.py +16 -0
- janito/cli_chat_shell/commands/prompt.py +42 -0
- janito/cli_chat_shell/commands/session_control.py +36 -1
- janito/cli_chat_shell/commands/termweb_log.py +86 -0
- janito/cli_chat_shell/commands/utility.py +5 -2
- janito/cli_chat_shell/commands/verbose.py +29 -0
- janito/cli_chat_shell/session_manager.py +9 -1
- janito/cli_chat_shell/shell_command_completer.py +20 -0
- janito/cli_chat_shell/ui.py +110 -99
- janito/i18n/__init__.py +35 -0
- janito/i18n/messages.py +23 -0
- janito/i18n/pt.py +46 -0
- janito/rich_utils.py +43 -43
- janito/termweb/app.py +95 -0
- janito/termweb/static/editor.html +238 -0
- janito/termweb/static/editor.html.bak +238 -0
- janito/termweb/static/explorer.html.bak +59 -0
- janito/termweb/static/favicon.ico +0 -0
- janito/termweb/static/favicon.ico.bak +0 -0
- janito/termweb/static/index.html +55 -0
- janito/termweb/static/index.html.bak +55 -0
- janito/termweb/static/index.html.bak.bak +175 -0
- janito/termweb/static/landing.html.bak +36 -0
- janito/termweb/static/termicon.svg +1 -0
- janito/termweb/static/termweb.css +235 -0
- janito/termweb/static/termweb.css.bak +286 -0
- janito/termweb/static/termweb.js +187 -0
- janito/termweb/static/termweb.js.bak +187 -0
- janito/termweb/static/termweb.js.bak.bak +157 -0
- janito/termweb/static/termweb_quickopen.js +135 -0
- janito/termweb/static/termweb_quickopen.js.bak +125 -0
- janito/web/app.py +4 -4
- {janito-1.7.0.dist-info → janito-1.8.0.dist-info}/METADATA +58 -25
- janito-1.8.0.dist-info/RECORD +127 -0
- {janito-1.7.0.dist-info → janito-1.8.0.dist-info}/WHEEL +1 -1
- janito/agent/templates/profiles/system_prompt_template_base.toml +0 -76
- janito/agent/templates/profiles/system_prompt_template_default.toml +0 -3
- janito/agent/templates/profiles/system_prompt_template_technical.toml +0 -13
- janito/agent/tests/test_prompt_toml.py +0 -61
- janito/agent/tool_registry_core.py +0 -2
- janito/agent/tools/get_file_outline.py +0 -146
- janito/agent/tools/py_compile_file.py +0 -40
- janito/agent/tools/replace_file.py +0 -51
- janito/agent/tools/search_files.py +0 -65
- janito/cli/runner/scan.py +0 -57
- janito/cli_chat_shell/commands/system.py +0 -73
- janito-1.7.0.dist-info/RECORD +0 -89
- {janito-1.7.0.dist-info → janito-1.8.0.dist-info}/entry_points.txt +0 -0
- {janito-1.7.0.dist-info → janito-1.8.0.dist-info}/licenses/LICENSE +0 -0
- {janito-1.7.0.dist-info → janito-1.8.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,127 @@
|
|
1
|
+
janito/__init__.py,sha256=TEX5rBxpQQMGbHlz1RNwQDTVirV3Dy0Px6DtRIL00_0,23
|
2
|
+
janito/__main__.py,sha256=KKIoPBE9xPcb54PRYO2UOt0ti04iAwLeJlg8YY36vew,76
|
3
|
+
janito/rich_utils.py,sha256=FZEwrRnd_G9dnhBpUus5c40dDs-XDr0tTnIoctZAEME,1128
|
4
|
+
janito/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
+
janito/agent/config.py,sha256=SMpyt9k1LhLn8DimhHcaOFmyk_iexEPnOREM1tWcMow,4616
|
6
|
+
janito/agent/config_defaults.py,sha256=mSS_NHNH8FrZOoX61ED8LktfOEUYT84Rfek0Oaue3MA,517
|
7
|
+
janito/agent/config_utils.py,sha256=UmvR236wDrMc-aTy9LxVbop6YeoJaaPb1d2DBMlkSRg,254
|
8
|
+
janito/agent/content_handler.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
+
janito/agent/conversation.py,sha256=8i6pm1gsOiE2y__nzBjt7LaigRRrqTtHkx3-SwyX_UE,7326
|
10
|
+
janito/agent/conversation_api.py,sha256=q6ZqbHdyo5vkHmXeu51Yfqf6cEjELUUAazew_IxGrHg,8200
|
11
|
+
janito/agent/conversation_exceptions.py,sha256=Aw7PRLb3eUfyDOGynKds5F48dgjyiOrTCEcWSprYC58,381
|
12
|
+
janito/agent/conversation_tool_calls.py,sha256=CJateY04z27ZHMorb5I4DpaeqFnjhX25uBjg1Foxpb0,1459
|
13
|
+
janito/agent/conversation_ui.py,sha256=y4f0IoJQoWGrFMB3yi7uIwXokuTjhFtJGK_R7zcTv3w,397
|
14
|
+
janito/agent/event.py,sha256=1jcua88NT-T4jA0mGIyIF1LvqXKu2GDT8NMjlelWmCI,517
|
15
|
+
janito/agent/event_dispatcher.py,sha256=eFNDfGY8o63yNLFdMe82LqfmDyGWjrAw9CpyUAcLJAM,856
|
16
|
+
janito/agent/event_handler_protocol.py,sha256=uIIf9u82BWm8pha4sZxydeEwgbxDoiWVSyplBPI0knE,130
|
17
|
+
janito/agent/event_system.py,sha256=QxPSQ2XeTyiWV6ejcmS8kTqTBrs7fLHRVXdhyeVHpas,608
|
18
|
+
janito/agent/message_handler.py,sha256=oZJ2u0C7OewHiHwlJslT2o3RPlvY2HhPXPoRcSsBv4M,856
|
19
|
+
janito/agent/message_handler_protocol.py,sha256=E8PLl9ucNvPK_xmhLEkV-vhQzfO_P_BMvzpqDvUkcVY,150
|
20
|
+
janito/agent/openai_client.py,sha256=oPbDFQoYzzD7XWw9E_4C_eqERc3Y5DkWyUcYRl7L8cs,4638
|
21
|
+
janito/agent/openai_schema_generator.py,sha256=WIE2kQYB0bPe_0IV3vA6OJHoW-uJr5ezHENNkmbH8bg,5762
|
22
|
+
janito/agent/platform_discovery.py,sha256=yp6KTvc-_u22Dr8-J4cdjVMUS8HkCf343aeSGRu2wek,2712
|
23
|
+
janito/agent/profile_manager.py,sha256=B-bwo1ZhtD2DaVPAfn0bNv1_inoduZhKGd694Pfy5GM,3231
|
24
|
+
janito/agent/queued_message_handler.py,sha256=sjsZneGWkqvfuJNac9QERdHasp9lWZvNcow8dul7tVU,1844
|
25
|
+
janito/agent/rich_live.py,sha256=NKWU89hRakiJ-0N6FPg40bYREOxQizqicbDv9eUfsKs,927
|
26
|
+
janito/agent/rich_message_handler.py,sha256=cSeTvdgHAPoSDddd5kFQNG2RnGj9kYMfuq6nzhtyJuE,2401
|
27
|
+
janito/agent/runtime_config.py,sha256=xSx0-RD-WVA9niSCEmEn2ZPLFbQfRhPwwGIa8tid_v8,901
|
28
|
+
janito/agent/test_handler_protocols.py,sha256=4o1IitFDUN1fdw48oQCRizKWahahumdmEZ4URHrlmiY,1404
|
29
|
+
janito/agent/tool_base.py,sha256=rf88iEX_uZ7MwkeDl4gGMtHeESg0dlFKUo2Jr_ZqDTY,1900
|
30
|
+
janito/agent/tool_executor.py,sha256=ltYdegI2-xpFZXVqclh3-Dv-yJEv3vIIuxZjirJovfI,4246
|
31
|
+
janito/agent/tool_registry.py,sha256=FlZ8YEoHdk2n7t8vZ26bVbu-fi4UeSE_yu2mZq8pusU,1594
|
32
|
+
janito/agent/tool_use_tracker.py,sha256=WJ1Pi5VlzDLrh-iDL3hNTC9IBfqr2QRPaz3n9w32q3o,1546
|
33
|
+
janito/agent/templates/profiles/system_prompt_template_base.txt.j2,sha256=-cSdepK7LC-d7iCFOreRnA5aYiaFuUvfrOSMWfz0_4s,676
|
34
|
+
janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2,sha256=FX8piXbR9XNOEKkOSMt4ieZ2wn5fzQlffeQFf8d7gIc,723
|
35
|
+
janito/agent/tests/__init__.py,sha256=QuXHKEzUJ_DooaKqenv_tKuNH-HabuIVZhvW5JNaeIc,52
|
36
|
+
janito/agent/tools/__init__.py,sha256=ulJfUtzEJFp8iPkpF6wSkNjSwqOZzePPuTY4WuFvIWE,1063
|
37
|
+
janito/agent/tools/ask_user.py,sha256=DL-jBU-njSjwhNSbgi23RZCrRBt5beDgZq_PG4yzbWM,3217
|
38
|
+
janito/agent/tools/create_directory.py,sha256=KQKt4o9pRu3ruDO9hDOxkcpzuyqxUqKlez5YFudKuXw,2481
|
39
|
+
janito/agent/tools/create_file.py,sha256=cmPhLIl_MozLIQZM38yQHC1a5R_jjFh8ZeqlFuWnETQ,3524
|
40
|
+
janito/agent/tools/dir_walk_utils.py,sha256=aE2UjCmmpJckcBKujq-1dGUGLWu7ryyAA7EzIbXPVtw,656
|
41
|
+
janito/agent/tools/fetch_url.py,sha256=ZJJXk-6avQUX7ezT982LuwrnU0R0Lryo1g1M6_fs3V8,2131
|
42
|
+
janito/agent/tools/find_files.py,sha256=n8k1US3_T23uZzXVD5Zx2t_wre1uiLnqUzQMEpGLzh4,3156
|
43
|
+
janito/agent/tools/get_lines.py,sha256=rYl9E6w3WKDrO3nhxLofWgYrLjncfD2R6dwUwuF-M6o,5148
|
44
|
+
janito/agent/tools/gitignore_utils.py,sha256=fDLyRZmCu6Hqhp1BEN8hs7oG0FtA-1SM9TGDz4g0lbw,1470
|
45
|
+
janito/agent/tools/memory.py,sha256=vvFGGTHJkh_SuLIrd1yzrEyGg_jfytVrKNhUhvUpYyA,1745
|
46
|
+
janito/agent/tools/move_file.py,sha256=rkiw4sSlhn9DmUcKadg9oMVvjl2jPqNRn-qXSe1zBt0,4339
|
47
|
+
janito/agent/tools/present_choices.py,sha256=e7SpOs3RIUXL6zi6PoeFc64akTVVuiQe2yLrm0rKpNs,2327
|
48
|
+
janito/agent/tools/present_choices_test.py,sha256=YYFki84vV1FT4MKnBgiwamjZyxUb2g5RDFQKmFF8Vdc,625
|
49
|
+
janito/agent/tools/remove_directory.py,sha256=aDNhXkUGHQU8bXIoIXjytYhODQFysjUerApBOOOa-1Y,2409
|
50
|
+
janito/agent/tools/remove_file.py,sha256=B5HOFCDhB8AgHgcgzMz_0y10yzPV7BSDrMwVYuMg1i4,2336
|
51
|
+
janito/agent/tools/replace_text_in_file.py,sha256=AZGPf4pjgAGqKlvvNdnbVTKZZkOgvyFEokg-5yPYE-w,9435
|
52
|
+
janito/agent/tools/rich_live.py,sha256=KpAN-dF0h9LZnYvSK-UKR_sbDnnDw0jUxY3cj_EW_wQ,1215
|
53
|
+
janito/agent/tools/run_bash_command.py,sha256=zJ08AC7oRMOTaRs34IVsGw3DuFM_KFicSkxWo6y86dU,7556
|
54
|
+
janito/agent/tools/run_powershell_command.py,sha256=Vgy4eghQ_x0AFvzj7n_-scOCzsATBpUAfa9SnIfUSjc,7863
|
55
|
+
janito/agent/tools/run_python_command.py,sha256=3cI7Vb63Aeogb0zp5AKqwNF4CysrDSMVXCaBGpeqdqs,7041
|
56
|
+
janito/agent/tools/search_outline.py,sha256=ubSvovxCRszrmSZ3NTgrbqadJ_lEAO8ohq910iyd7zw,698
|
57
|
+
janito/agent/tools/search_text.py,sha256=eYk70KW24syvdPtFku1-_dpdcM2vgmcu-B37XlcMJ1U,9240
|
58
|
+
janito/agent/tools/tools_utils.py,sha256=NNKRfzFpqUR7gS4RKmigO7PM9WAw_M6mkQH1c4rHKDg,2090
|
59
|
+
janito/agent/tools/utils.py,sha256=igD1FBUFCmzSxt8WQRbLEYqXngupXrhfdzquYaWv4ng,932
|
60
|
+
janito/agent/tools/validate_file_syntax.py,sha256=ngxkb85YwDbraiJXiWwPCA3wTZJTv_KgBu8uv0KuBHY,7558
|
61
|
+
janito/agent/tools/outline_file/__init__.py,sha256=Y3UK2zE8UnZyM9mOIKHMr38_8x1BhtYWWsg4luRmOVQ,3315
|
62
|
+
janito/agent/tools/outline_file/formatting.py,sha256=AB44kMT6LRVW2fNqX2u2Re7B1Dy3qqObfQHRhcDd9Ow,913
|
63
|
+
janito/agent/tools/outline_file/markdown_outline.py,sha256=bXEBg0D93tEBDNy8t-wh4i7WxsxfpQ2C3dX1_rmtj08,434
|
64
|
+
janito/agent/tools/outline_file/python_outline.py,sha256=8Y6UYRSSrFmhndwGUTQacVIvFZvPVu8B91oqZhia4q8,2571
|
65
|
+
janito/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
66
|
+
janito/cli/_print_config.py,sha256=C_27QdwzhqorzeJflBFK0f46zTUtqqmdYe3EBurjOOE,3574
|
67
|
+
janito/cli/_utils.py,sha256=tRAUMDWKczd81ZvKYkwpsHWSeLzQoVlOoQ-lOw9Iujw,291
|
68
|
+
janito/cli/arg_parser.py,sha256=fnR9hKmQn_aIZz4hT8kr7tq31KDjkkFW-boNsrcPau8,6873
|
69
|
+
janito/cli/config_commands.py,sha256=vfU7XciVMRNR5kDvn6tnCo1PLvSEXg0Y0PzLcDEFI9w,8539
|
70
|
+
janito/cli/logging_setup.py,sha256=_KLF69xqq1xLPIfkXxy0EIewO-Ef2eYoxNVjqjsC0vc,1361
|
71
|
+
janito/cli/main.py,sha256=Njsvs-x22p4WumR0Z4lpG3KwRz18hoSQBdiGAW9Tces,5312
|
72
|
+
janito/cli/termweb_starter.py,sha256=Ky9qJPQ8nY3TOeDHmq-IZvWNZa4m68IVeCZqNTQ9RFY,2795
|
73
|
+
janito/cli/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
74
|
+
janito/cli/runner/_termweb_log_utils.py,sha256=QpH40uxPhksrJHWqthW4cR7BhcSSYakpza_qTeFGABs,722
|
75
|
+
janito/cli/runner/cli_main.py,sha256=Y74v_F39XCCkrv0aAJTXXNZQfdBjoISZYGkefrZNJf8,6880
|
76
|
+
janito/cli/runner/config.py,sha256=Nzam25C8P55dFlT_f6IlEj2ZvFwS63AAbnkIWe3oNsg,1702
|
77
|
+
janito/cli/runner/formatting.py,sha256=k0mtHoglqR8fKcebSK81iWTT_EL-gDl7eNfjlFZRY6g,287
|
78
|
+
janito/cli_chat_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
79
|
+
janito/cli_chat_shell/chat_loop.py,sha256=DNuM2VM6FOjcY-2017HCiGeX6hO_9f0iBqlrTO-FpXo,5832
|
80
|
+
janito/cli_chat_shell/chat_state.py,sha256=Gf8gyh60SYdD_G5rSwJTKto96UHVaPrQlkRcceoN8yU,1221
|
81
|
+
janito/cli_chat_shell/chat_ui.py,sha256=3cw2Mu4u0T60malPy-SXFA3vW0MtGMCQcHAZYO-Irfw,1272
|
82
|
+
janito/cli_chat_shell/config_shell.py,sha256=sG04S_z27wI7nXKMaVDcwDpBCuo6Cvd4uhutUQesJKo,3807
|
83
|
+
janito/cli_chat_shell/load_prompt.py,sha256=gHedc5TtaFBKiGgwRM_u9nVnBuLHDTSa8VPlPOtoMEA,2125
|
84
|
+
janito/cli_chat_shell/session_manager.py,sha256=J3K5fzObwjIDSUfyKOdr8Db2jcoFGf1M4nmtYhQXpq4,2365
|
85
|
+
janito/cli_chat_shell/shell_command_completer.py,sha256=bEpfHlMqmGlTeV2wzl0xSungEl1_2eo488qxx5_ia1w,764
|
86
|
+
janito/cli_chat_shell/ui.py,sha256=6wqKFSJyILPLnzwoAVpkqFc95Mh8HkLr9DN3Sl6mC-k,7213
|
87
|
+
janito/cli_chat_shell/commands/__init__.py,sha256=3rpT6fFPP50qEePRQNOIQmmuU0U7bKRK9DnHZ0pNkNU,1777
|
88
|
+
janito/cli_chat_shell/commands/config.py,sha256=JTQwIuSBunxDwvGsU_Cu78GkQNYCtDFTPZ7HOxNOZCY,945
|
89
|
+
janito/cli_chat_shell/commands/history_start.py,sha256=JUwxaKatqMWWn0yCC5S2YDVVTfAQCpJG6oPBuW4nYWo,1139
|
90
|
+
janito/cli_chat_shell/commands/lang.py,sha256=cG_gX61LUgzv_Bxk-UPTTNF1JQFfcUVaYBnPovUylNw,521
|
91
|
+
janito/cli_chat_shell/commands/prompt.py,sha256=YVW1uHfYVPPNvcGoQeHWOwyfpGhCAgSmv670xjRnLs4,1713
|
92
|
+
janito/cli_chat_shell/commands/session.py,sha256=64H9UYB-LRSWzMar_C7iNM06MqrKmpRm_Dk9XXIMCiM,1739
|
93
|
+
janito/cli_chat_shell/commands/session_control.py,sha256=m4SolmEi7RMHe4WZiUlHQfTIzS0KDT_PYqvnetEm4fs,1398
|
94
|
+
janito/cli_chat_shell/commands/sum.py,sha256=S_46ubHUnGoLNwL5_0VeDmA5YYo99aX8baZuBdU1gZ8,1829
|
95
|
+
janito/cli_chat_shell/commands/termweb_log.py,sha256=6hU2K-cZUHCC1-l7bBMjyB6illSX_eB28opdGa9dz6g,3219
|
96
|
+
janito/cli_chat_shell/commands/utility.py,sha256=PdCkb4UpvyE5jr5o_zZpgfiCXzH4ma_3FjAl2_y0qsU,1145
|
97
|
+
janito/cli_chat_shell/commands/verbose.py,sha256=woN1-suIGBnoxTzkoZomOrK6KEl64mDPc0bgO3ToBOI,997
|
98
|
+
janito/i18n/__init__.py,sha256=7HYvwOTTf51pVm4adU79rl1FCtAjgOy6GzeShfYCdQY,970
|
99
|
+
janito/i18n/messages.py,sha256=fBuwOTFoygyHPkYphm6Y0r1iE8497Z4iryVAmPhMEkg,1851
|
100
|
+
janito/i18n/pt.py,sha256=52-ENCIrPW4A1tXFRT28xA8TwuUFoihs6ezJj-m3-Y4,4260
|
101
|
+
janito/termweb/app.py,sha256=TO_oWHGqrud4Fhf4DcExc40hCHzyO3P99pZm4oA5INM,3374
|
102
|
+
janito/termweb/static/editor.html,sha256=T5IeILW4yFIm5ZbNTqUJjqDldv7ACIdHF8AsZdv7T9M,8859
|
103
|
+
janito/termweb/static/editor.html.bak,sha256=rFm5Y_-Rh_03Hs19gzfVu3IBmljIsuPduen2gDKQEyg,8862
|
104
|
+
janito/termweb/static/explorer.html.bak,sha256=PM1fcbaQJm545WT94mVEekUNW3jduBAHOz6rwJBR1FA,2568
|
105
|
+
janito/termweb/static/favicon.ico,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
106
|
+
janito/termweb/static/favicon.ico.bak,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
107
|
+
janito/termweb/static/index.html,sha256=MCCF7ncTEBsE-c829jy3UnkVsIKmnfm0vt3s54cmwcQ,3124
|
108
|
+
janito/termweb/static/index.html.bak,sha256=SB6bQFktnZpJzMeo1CzlC82XkYpLcpLnjv1uMS-11FQ,3123
|
109
|
+
janito/termweb/static/index.html.bak.bak,sha256=dsKoC2lE0oJCGUUDTWcnIQE3s5Uoqd12WoTkWEwbH_c,6626
|
110
|
+
janito/termweb/static/landing.html.bak,sha256=JGwIcATj0B8MhHXLoXg2clypqsKJwi54NtW-rRDUsMs,1403
|
111
|
+
janito/termweb/static/termicon.svg,sha256=vc2Z3q-ADVK3pLzE3wnw_qpR6vDguWKEdH_pWObPjbw,229
|
112
|
+
janito/termweb/static/termweb.css,sha256=9AxhC2R8CzS82NHg9bk0GD-kxKt_NeRSRFGgTyi-3zI,4870
|
113
|
+
janito/termweb/static/termweb.css.bak,sha256=PICa5u6RgaXDg47EGOEn1Yt63k7Wm8mW1vc3zSUU-hs,6004
|
114
|
+
janito/termweb/static/termweb.js,sha256=SgXq3FWGl4ltUeQeamT6YRQJ7RFdy9EPaD6iSvq1uSs,9093
|
115
|
+
janito/termweb/static/termweb.js.bak,sha256=Y62Uew5kb3I6Fs5hZBcREArymigU7NHHrKdoaswqjyc,9131
|
116
|
+
janito/termweb/static/termweb.js.bak.bak,sha256=SQeqc9YwdreCmFJ7LtCYlHOjRHi8rsoW_fZ3x5WroWQ,7692
|
117
|
+
janito/termweb/static/termweb_quickopen.js,sha256=HNT85JjWAvjI5ROwukOU-oI4ZVVjCO6yg5IT115pdXI,5379
|
118
|
+
janito/termweb/static/termweb_quickopen.js.bak,sha256=sk_zbEw6HJt1iZSAYlaW0qAhq0to-KcBsOKx0AZqkKA,4814
|
119
|
+
janito/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
120
|
+
janito/web/__main__.py,sha256=5Ck6okOZmxKYkQ-ir4mxXDH7XWMNR-9szgsm0UyQLE0,734
|
121
|
+
janito/web/app.py,sha256=NarccXYgeYEMvws1lQSGZtArrzJIvw94LSNR0rW9Dq4,7331
|
122
|
+
janito-1.8.0.dist-info/licenses/LICENSE,sha256=sHBqv0bvtrb29H7WRR-Z603YHm9pLtJIo3nHU_9cmgE,1091
|
123
|
+
janito-1.8.0.dist-info/METADATA,sha256=3F51ULeTzBgxUVFZs5cemk1bX1ZFUfRfzpFr6V0WTK8,12479
|
124
|
+
janito-1.8.0.dist-info/WHEEL,sha256=ck4Vq1_RXyvS4Jt6SI0Vz6fyVs4GWg7AINwpsaGEgPE,91
|
125
|
+
janito-1.8.0.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
|
126
|
+
janito-1.8.0.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
|
127
|
+
janito-1.8.0.dist-info/RECORD,,
|
@@ -1,76 +0,0 @@
|
|
1
|
-
# Base system prompt template for Janito agent styles
|
2
|
-
[agent_profile]
|
3
|
-
role = "${role}"
|
4
|
-
description = "Agent for analysis and development tool operating on files and directories using text-based operations."
|
5
|
-
|
6
|
-
[platform]
|
7
|
-
platform = "${platform}"
|
8
|
-
python_version = "${python_version}"
|
9
|
-
shell_info = "${shell_info}"
|
10
|
-
notes = """
|
11
|
-
- Always pay careful attention to platform-specific path conventions (e.g., path separator, drive letters, case sensitivity), Python version differences, and shell/command syntax when reading, writing, or executing files and commands.
|
12
|
-
- If running in a non-standard shell (such as Git Bash or WSL on Windows), be extra cautious about path and command compatibility.
|
13
|
-
"""
|
14
|
-
|
15
|
-
[tech]
|
16
|
-
exists = "${tech_txt_exists}"
|
17
|
-
content = """
|
18
|
-
${tech_txt_content}
|
19
|
-
"""
|
20
|
-
|
21
|
-
[operational_workflow]
|
22
|
-
steps = """
|
23
|
-
- Provide a concise plan before calling any tool.
|
24
|
-
- Plan changes only after gathering all the necessary information.
|
25
|
-
- Always execute the plan immediately after presenting it, unless the user requests otherwise.
|
26
|
-
"""
|
27
|
-
|
28
|
-
[safety_guidelines]
|
29
|
-
steps = """
|
30
|
-
- Always update all references and validate the system before removing or renaming files.
|
31
|
-
- Only remove or rename files after all dependent code has been updated and validated.
|
32
|
-
- Prefer the following order for destructive operations:
|
33
|
-
1. Update all imports/references.
|
34
|
-
2. Validate the changes using the tools available to test the type of file changed.
|
35
|
-
3. Remove or rename the file.
|
36
|
-
4. Re-validate the system.
|
37
|
-
- Roll back changes if any validation step fails.
|
38
|
-
"""
|
39
|
-
|
40
|
-
[context]
|
41
|
-
steps = """
|
42
|
-
- Before answering, always examine the contents of files that are directly related to the user's question or request, and explore the project structure to understand existing directories, files, and their purposes.
|
43
|
-
- Always review `README_structure.txt` before conducting file-specific searches.
|
44
|
-
- Unless specified otherwise, look for the files that match the questions context.
|
45
|
-
- Explore files that might be relevant to the current task.
|
46
|
-
- Before providing a detailed plan, always examine the contents of files that are directly related to the user's question or request.
|
47
|
-
"""
|
48
|
-
|
49
|
-
[analysis]
|
50
|
-
steps = """
|
51
|
-
- In case of missing code or functions, look into the .bak files and check git diff/history for recent changes.
|
52
|
-
"""
|
53
|
-
|
54
|
-
[decision_policy]
|
55
|
-
steps = """
|
56
|
-
- Whenever there is uncertainty, ambiguity, missing information, or multiple valid options, request clarification or input from the user. Otherwise, proceed and inform the user of the decision_policy made.
|
57
|
-
- When making changes, prefer optimal, effective, and natural edits. Perform larger refactors, reorganizations, or multi-region edits when they lead to better results, rather than restricting to minimal or single-region changes. Avoid unnecessary splitting of text ranges. Validate changes using available tools before proceeding.
|
58
|
-
"""
|
59
|
-
|
60
|
-
[finalization]
|
61
|
-
steps = """
|
62
|
-
- Review the README content if there are user-exposed or public API changes.
|
63
|
-
- Update documentation and metadata (e.g., README_structure.txt) to reflect new or modified files.
|
64
|
-
- When updating documentation, recommend (when appropriate) adding a footer or note such as: _'generated by janito.dev'_
|
65
|
-
"""
|
66
|
-
|
67
|
-
[interaction_mode]
|
68
|
-
current = "${interaction_mode}"
|
69
|
-
notes = """
|
70
|
-
- Always adapt your clarification and interaction strategy to the current mode.
|
71
|
-
"""
|
72
|
-
|
73
|
-
[function_call_summary]
|
74
|
-
steps = """
|
75
|
-
- Before executing any function calls, emit a concise summary message describing the planned actions, reasoning, and expected outcomes.
|
76
|
-
"""
|
@@ -1,13 +0,0 @@
|
|
1
|
-
# Inherits from system_prompt_template_base.toml
|
2
|
-
extends = "system_prompt_template_base.toml"
|
3
|
-
|
4
|
-
[agent_profile]
|
5
|
-
description = "This Agent follows its Agent Profile, including system settings, role, and toolchain constraints."
|
6
|
-
|
7
|
-
[technical_workflow]
|
8
|
-
steps = """
|
9
|
-
- Enumerate and validate the current file system state before any operation.
|
10
|
-
- Use the tools available to test and validate the type of file changed, inferring dependencies, side effects, and potential conflicts.
|
11
|
-
- Explicitly handle errors, edge cases, and race conditions. Log all exceptions and recovery actions.
|
12
|
-
- Maintain traceability: document all actions, decision_policys, and state transitions.
|
13
|
-
"""
|
@@ -1,61 +0,0 @@
|
|
1
|
-
from janito.agent.profile_manager import AgentProfileManager
|
2
|
-
|
3
|
-
|
4
|
-
def test_prompt_default(monkeypatch):
|
5
|
-
mgr = AgentProfileManager(
|
6
|
-
api_key="sk-test",
|
7
|
-
model="gpt-test",
|
8
|
-
role="software engineer",
|
9
|
-
interaction_style="default",
|
10
|
-
interaction_mode="chat",
|
11
|
-
verbose_tools=False,
|
12
|
-
base_url="https://test",
|
13
|
-
azure_openai_api_version="2023-05-15",
|
14
|
-
use_azure_openai=False,
|
15
|
-
)
|
16
|
-
prompt = mgr.render_prompt()
|
17
|
-
assert "[agent_profile]" in prompt
|
18
|
-
assert "software engineer" in prompt
|
19
|
-
assert "[platform]" in prompt
|
20
|
-
assert "Always pay careful attention" in prompt
|
21
|
-
assert "[function_call_summary]" in prompt
|
22
|
-
|
23
|
-
|
24
|
-
def test_prompt_technical(monkeypatch):
|
25
|
-
mgr = AgentProfileManager(
|
26
|
-
api_key="sk-test",
|
27
|
-
model="gpt-test",
|
28
|
-
role="software engineer",
|
29
|
-
interaction_style="technical",
|
30
|
-
interaction_mode="chat",
|
31
|
-
verbose_tools=False,
|
32
|
-
base_url="https://test",
|
33
|
-
azure_openai_api_version="2023-05-15",
|
34
|
-
use_azure_openai=False,
|
35
|
-
)
|
36
|
-
prompt = mgr.render_prompt()
|
37
|
-
assert "[agent_profile]" in prompt
|
38
|
-
assert "strict adherence" in prompt
|
39
|
-
assert "[technical_workflow]" in prompt
|
40
|
-
assert "Enumerate and validate the current file system state" in prompt
|
41
|
-
assert "[function_call_summary]" in prompt
|
42
|
-
|
43
|
-
|
44
|
-
def test_prompt_inheritance(monkeypatch):
|
45
|
-
mgr = AgentProfileManager(
|
46
|
-
api_key="sk-test",
|
47
|
-
model="gpt-test",
|
48
|
-
role="software engineer",
|
49
|
-
interaction_style="technical",
|
50
|
-
interaction_mode="chat",
|
51
|
-
verbose_tools=False,
|
52
|
-
base_url="https://test",
|
53
|
-
azure_openai_api_version="2023-05-15",
|
54
|
-
use_azure_openai=False,
|
55
|
-
)
|
56
|
-
prompt = mgr.render_prompt()
|
57
|
-
# Should inherit context, analysis, etc. from base
|
58
|
-
assert "[context]" in prompt
|
59
|
-
assert "[analysis]" in prompt
|
60
|
-
assert "[decision_policy]" in prompt
|
61
|
-
assert "[finalization]" in prompt
|
@@ -1,146 +0,0 @@
|
|
1
|
-
from janito.agent.tool_base import ToolBase
|
2
|
-
from janito.agent.tool_registry import register_tool
|
3
|
-
import os
|
4
|
-
import re
|
5
|
-
from typing import List
|
6
|
-
|
7
|
-
|
8
|
-
@register_tool(name="get_file_outline")
|
9
|
-
class GetFileOutlineTool(ToolBase):
|
10
|
-
"""
|
11
|
-
Get an outline of a file's structure.
|
12
|
-
|
13
|
-
Note:
|
14
|
-
The outline extraction for Python files is based on regular expression (regex) pattern matching for class and function definitions.
|
15
|
-
This approach may not capture all edge cases or non-standard code structures. For complex files, further examination or more advanced parsing may be required.
|
16
|
-
|
17
|
-
Args:
|
18
|
-
file_path (str): Path to the file.
|
19
|
-
Returns:
|
20
|
-
str: Outline of the file's structure, starting with a summary line. Example:
|
21
|
-
- "Outline: 5 items (python)\n| Type | Name | Start | End | Parent |\n|---------|-------------|-------|-----|----------|\n| class | MyClass | 1 | 20 | |\n| method | my_method | 3 | 10 | MyClass |\n| function| my_func | 22 | 30 | |\n..."
|
22
|
-
- "Outline: 100 lines (default)\nFile has 100 lines."
|
23
|
-
- "Error reading file: <error message>"
|
24
|
-
"""
|
25
|
-
|
26
|
-
def call(self, file_path: str) -> str:
|
27
|
-
from janito.agent.tools.tools_utils import display_path
|
28
|
-
|
29
|
-
disp_path = display_path(file_path)
|
30
|
-
self.report_info(f"📄 Getting outline for: {disp_path}")
|
31
|
-
|
32
|
-
try:
|
33
|
-
ext = os.path.splitext(file_path)[1].lower()
|
34
|
-
with open(file_path, "r", encoding="utf-8", errors="replace") as f:
|
35
|
-
lines = f.readlines()
|
36
|
-
if ext == ".py":
|
37
|
-
outline_items = self._parse_python_outline(lines)
|
38
|
-
outline_type = "python"
|
39
|
-
table = self._format_outline_table(outline_items)
|
40
|
-
self.report_success(f"✅ {len(outline_items)} items ({outline_type})")
|
41
|
-
return f"Outline: {len(outline_items)} items ({outline_type})\n" + table
|
42
|
-
elif ext == ".md":
|
43
|
-
outline_items = self._parse_markdown_outline(lines)
|
44
|
-
outline_type = "markdown"
|
45
|
-
table = self._format_markdown_outline_table(outline_items)
|
46
|
-
self.report_success(f"✅ {len(outline_items)} items ({outline_type})")
|
47
|
-
return f"Outline: {len(outline_items)} items ({outline_type})\n" + table
|
48
|
-
else:
|
49
|
-
outline_type = "default"
|
50
|
-
self.report_success(f"✅ {len(lines)} lines ({outline_type})")
|
51
|
-
return f"Outline: {len(lines)} lines ({outline_type})\nFile has {len(lines)} lines."
|
52
|
-
except Exception as e:
|
53
|
-
self.report_error(f"❌ Error reading file: {e}")
|
54
|
-
return f"Error reading file: {e}"
|
55
|
-
|
56
|
-
def _parse_python_outline(self, lines: List[str]):
|
57
|
-
# Regex for class, function, and method definitions
|
58
|
-
class_pat = re.compile(r"^(\s*)class\s+(\w+)")
|
59
|
-
func_pat = re.compile(r"^(\s*)def\s+(\w+)")
|
60
|
-
outline = []
|
61
|
-
stack = [] # (name, type, indent, start, parent)
|
62
|
-
for idx, line in enumerate(lines):
|
63
|
-
class_match = class_pat.match(line)
|
64
|
-
func_match = func_pat.match(line)
|
65
|
-
indent = len(line) - len(line.lstrip())
|
66
|
-
if class_match:
|
67
|
-
name = class_match.group(2)
|
68
|
-
parent = stack[-1][1] if stack and stack[-1][0] == "class" else ""
|
69
|
-
stack.append(("class", name, indent, idx + 1, parent))
|
70
|
-
elif func_match:
|
71
|
-
name = func_match.group(2)
|
72
|
-
parent = (
|
73
|
-
stack[-1][1]
|
74
|
-
if stack
|
75
|
-
and stack[-1][0] in ("class", "function")
|
76
|
-
and indent > stack[-1][2]
|
77
|
-
else ""
|
78
|
-
)
|
79
|
-
stack.append(("function", name, indent, idx + 1, parent))
|
80
|
-
# Pop stack if indentation decreases
|
81
|
-
while stack and indent < stack[-1][2]:
|
82
|
-
popped = stack.pop()
|
83
|
-
outline.append(
|
84
|
-
{
|
85
|
-
"type": (
|
86
|
-
popped[0]
|
87
|
-
if popped[0] != "function" or popped[3] == 1
|
88
|
-
else ("method" if popped[4] else "function")
|
89
|
-
),
|
90
|
-
"name": popped[1],
|
91
|
-
# Add end line for popped item
|
92
|
-
"start": popped[3],
|
93
|
-
"end": idx,
|
94
|
-
"parent": popped[4],
|
95
|
-
}
|
96
|
-
)
|
97
|
-
# Pop any remaining items in the stack at EOF
|
98
|
-
for popped in stack:
|
99
|
-
outline.append(
|
100
|
-
{
|
101
|
-
"type": (
|
102
|
-
popped[0]
|
103
|
-
if popped[0] != "function" or popped[3] == 1
|
104
|
-
else ("method" if popped[4] else "function")
|
105
|
-
),
|
106
|
-
"name": popped[1],
|
107
|
-
"start": popped[3],
|
108
|
-
"end": len(lines),
|
109
|
-
"parent": popped[4],
|
110
|
-
}
|
111
|
-
)
|
112
|
-
return outline
|
113
|
-
|
114
|
-
def _parse_markdown_outline(self, lines: List[str]):
|
115
|
-
# Extract Markdown headers (e.g., #, ##, ###)
|
116
|
-
header_pat = re.compile(r"^(#+)\s+(.*)")
|
117
|
-
outline = []
|
118
|
-
for idx, line in enumerate(lines):
|
119
|
-
match = header_pat.match(line)
|
120
|
-
if match:
|
121
|
-
level = len(match.group(1))
|
122
|
-
title = match.group(2).strip()
|
123
|
-
outline.append({"level": level, "title": title, "line": idx + 1})
|
124
|
-
return outline
|
125
|
-
|
126
|
-
def _format_markdown_outline_table(self, outline_items):
|
127
|
-
if not outline_items:
|
128
|
-
return "No headers found."
|
129
|
-
header = "| Level | Header | Line |\n|-------|----------------------------------|------|"
|
130
|
-
rows = []
|
131
|
-
for item in outline_items:
|
132
|
-
rows.append(
|
133
|
-
f"| {item['level']:<5} | {item['title']:<32} | {item['line']:<4} |"
|
134
|
-
)
|
135
|
-
return header + "\n" + "\n".join(rows)
|
136
|
-
|
137
|
-
def _format_outline_table(self, outline_items):
|
138
|
-
if not outline_items:
|
139
|
-
return "No classes or functions found."
|
140
|
-
header = "| Type | Name | Start | End | Parent |\n|---------|-------------|-------|-----|----------|"
|
141
|
-
rows = []
|
142
|
-
for item in outline_items:
|
143
|
-
rows.append(
|
144
|
-
f"| {item['type']:<7} | {item['name']:<11} | {item['start']:<5} | {item['end']:<3} | {item['parent']:<8} |"
|
145
|
-
)
|
146
|
-
return header + "\n" + "\n".join(rows)
|
@@ -1,40 +0,0 @@
|
|
1
|
-
from janito.agent.tool_base import ToolBase
|
2
|
-
from janito.agent.tool_registry import register_tool
|
3
|
-
|
4
|
-
from typing import Optional
|
5
|
-
import py_compile
|
6
|
-
|
7
|
-
|
8
|
-
@register_tool(name="py_compile_file")
|
9
|
-
class PyCompileFileTool(ToolBase):
|
10
|
-
"""
|
11
|
-
Validate a Python file by compiling it with py_compile.
|
12
|
-
Useful to validate python files after changing them, especially after import changes.
|
13
|
-
|
14
|
-
Args:
|
15
|
-
file_path (str): Path to the Python file to compile.
|
16
|
-
doraise (bool, optional): Whether to raise exceptions on compilation errors. Defaults to True.
|
17
|
-
Returns:
|
18
|
-
str: Compilation status message. Example:
|
19
|
-
- "✅ Compiled"
|
20
|
-
- "Compile error: <error message>"
|
21
|
-
- "Error: <error message>"
|
22
|
-
"""
|
23
|
-
|
24
|
-
def call(self, file_path: str, doraise: Optional[bool] = True) -> str:
|
25
|
-
self.report_info(f"🛠️ Compiling Python file: {file_path}")
|
26
|
-
|
27
|
-
if not (file_path.endswith(".py") or file_path.endswith(".pyw")):
|
28
|
-
msg = f"Error: {file_path} is not a Python (.py/.pyw) file."
|
29
|
-
self.report_error(f" [py_compile_file] {msg}")
|
30
|
-
return msg
|
31
|
-
try:
|
32
|
-
py_compile.compile(file_path, doraise=doraise)
|
33
|
-
self.report_success(" ✅ Compiled")
|
34
|
-
return "✅ Compiled"
|
35
|
-
except py_compile.PyCompileError as e:
|
36
|
-
self.report_error(f" [py_compile_file] Compile error: {e}")
|
37
|
-
return f"Compile error: {e}"
|
38
|
-
except Exception as e:
|
39
|
-
self.report_error(f" [py_compile_file] Error: {e}")
|
40
|
-
return f"Error: {e}"
|
@@ -1,51 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import shutil
|
3
|
-
from janito.agent.tool_registry import register_tool
|
4
|
-
from janito.agent.tools.utils import expand_path, display_path
|
5
|
-
from janito.agent.tool_base import ToolBase
|
6
|
-
|
7
|
-
|
8
|
-
@register_tool(name="replace_file")
|
9
|
-
class ReplaceFileTool(ToolBase):
|
10
|
-
"""
|
11
|
-
Overwrite (replace) a file with the given content. Creates the file if it does not exist.
|
12
|
-
|
13
|
-
Args:
|
14
|
-
path (str): Path to the file to overwrite or create.
|
15
|
-
content (str): Content to write to the file.
|
16
|
-
backup (bool, optional): If True, create a backup (.bak) before replacing if the file exists. Recommend using backup=True only in the first call to avoid redundant backups. Defaults to False.
|
17
|
-
Returns:
|
18
|
-
str: Status message indicating the result. Example:
|
19
|
-
- "\u2705 Successfully replaced the file at ..."
|
20
|
-
- "\u2705 Successfully created the file at ..."
|
21
|
-
"""
|
22
|
-
|
23
|
-
def call(self, path: str, content: str, backup: bool = False) -> str:
|
24
|
-
original_path = path
|
25
|
-
path = expand_path(path)
|
26
|
-
disp_path = display_path(original_path, path)
|
27
|
-
updating = os.path.exists(path) and not os.path.isdir(path)
|
28
|
-
if os.path.exists(path) and os.path.isdir(path):
|
29
|
-
self.report_error("\u274c Error: is a directory")
|
30
|
-
return (
|
31
|
-
f"\u274c Cannot replace file: '{disp_path}' is an existing directory."
|
32
|
-
)
|
33
|
-
# Ensure parent directories exist
|
34
|
-
dir_name = os.path.dirname(path)
|
35
|
-
if dir_name:
|
36
|
-
os.makedirs(dir_name, exist_ok=True)
|
37
|
-
if backup and os.path.exists(path) and not os.path.isdir(path):
|
38
|
-
shutil.copy2(path, path + ".bak")
|
39
|
-
with open(path, "w", encoding="utf-8", errors="replace") as f:
|
40
|
-
f.write(content)
|
41
|
-
new_lines = content.count("\n") + 1 if content else 0
|
42
|
-
if updating:
|
43
|
-
self.report_success(
|
44
|
-
f"\u2705 Successfully replaced the file at '{disp_path}' ({new_lines} lines)."
|
45
|
-
)
|
46
|
-
return f"\u2705 Successfully replaced the file at '{disp_path}' ({new_lines} lines)."
|
47
|
-
else:
|
48
|
-
self.report_success(
|
49
|
-
f"\u2705 Successfully created the file at '{disp_path}' ({new_lines} lines)."
|
50
|
-
)
|
51
|
-
return f"\u2705 Successfully created the file at '{disp_path}' ({new_lines} lines)."
|
@@ -1,65 +0,0 @@
|
|
1
|
-
from janito.agent.tool_base import ToolBase
|
2
|
-
from janito.agent.tool_registry import register_tool
|
3
|
-
from janito.agent.tools.tools_utils import pluralize
|
4
|
-
|
5
|
-
import os
|
6
|
-
from janito.agent.tools.gitignore_utils import filter_ignored
|
7
|
-
|
8
|
-
|
9
|
-
@register_tool(name="search_files")
|
10
|
-
class SearchFilesTool(ToolBase):
|
11
|
-
"""
|
12
|
-
Search for a text pattern in all files within a directory and return matching lines. Respects .gitignore.
|
13
|
-
|
14
|
-
Args:
|
15
|
-
directories (list[str]): List of directories to search in.
|
16
|
-
pattern (str): Plain text substring to search for in files. (Not a regular expression or glob pattern.)
|
17
|
-
recursive (bool): Whether to search recursively in subdirectories. Defaults to True.
|
18
|
-
Returns:
|
19
|
-
str: Matching lines from files as a newline-separated string, each formatted as 'filepath:lineno: line'. Example:
|
20
|
-
- "/path/to/file.py:10: def my_function():"
|
21
|
-
- "Warning: Empty search pattern provided. Operation skipped."
|
22
|
-
"""
|
23
|
-
|
24
|
-
def call(
|
25
|
-
self,
|
26
|
-
directories: list[str],
|
27
|
-
pattern: str,
|
28
|
-
recursive: bool = True,
|
29
|
-
) -> str:
|
30
|
-
if not pattern:
|
31
|
-
self.report_warning(
|
32
|
-
"⚠️ Warning: Empty search pattern provided. Operation skipped."
|
33
|
-
)
|
34
|
-
return "Warning: Empty search pattern provided. Operation skipped."
|
35
|
-
output = []
|
36
|
-
for directory in directories:
|
37
|
-
info_str = f"🔎 Searching for text '{pattern}' in '{directory}'"
|
38
|
-
if recursive is False:
|
39
|
-
info_str += f" (recursive={recursive})"
|
40
|
-
self.report_info(info_str)
|
41
|
-
if recursive:
|
42
|
-
walker = os.walk(directory)
|
43
|
-
else:
|
44
|
-
# Only the top directory, not recursive
|
45
|
-
dirs, files = filter_ignored(
|
46
|
-
directory, *os.walk(directory).__next__()[1:]
|
47
|
-
)
|
48
|
-
walker = [(directory, dirs, files)]
|
49
|
-
for root, dirs, files in walker:
|
50
|
-
rel_path = os.path.relpath(root, directory)
|
51
|
-
depth = 0 if rel_path == "." else rel_path.count(os.sep) + 1
|
52
|
-
if not recursive and depth > 0:
|
53
|
-
break
|
54
|
-
dirs, files = filter_ignored(root, dirs, files)
|
55
|
-
for filename in files:
|
56
|
-
path = os.path.join(root, filename)
|
57
|
-
try:
|
58
|
-
with open(path, "r", encoding="utf-8", errors="ignore") as f:
|
59
|
-
for lineno, line in enumerate(f, 1):
|
60
|
-
if pattern in line:
|
61
|
-
output.append(f"{path}:{lineno}: {line.strip()}")
|
62
|
-
except Exception:
|
63
|
-
continue
|
64
|
-
self.report_success(f" ✅ {len(output)} {pluralize('line', len(output))} found")
|
65
|
-
return "\n".join(output)
|