PyBreeze 1.0.28__tar.gz → 1.0.30__tar.gz

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.
Files changed (202) hide show
  1. {pybreeze-1.0.28 → pybreeze-1.0.30}/PKG-INFO +1 -1
  2. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend_multi_language/extend_english.py +2 -0
  3. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend_multi_language/extend_traditional_chinese.py +2 -0
  4. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/ai_gui_global_variable.py +16 -0
  5. pybreeze-1.0.30/pybreeze/pybreeze_ui/extend_ai_gui/code_review/code_review_thread.py +75 -0
  6. pybreeze-1.0.30/pybreeze/pybreeze_ui/extend_ai_gui/code_review/cot_chain.py +100 -0
  7. pybreeze-1.0.30/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_prompt_editor_widget.py +34 -0
  8. pybreeze-1.0.30/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/prompt_editor_widget.py +165 -0
  9. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/prompt_file_io.py +5 -0
  10. pybreeze-1.0.30/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_editor_widget.py +34 -0
  11. pybreeze-1.0.30/pybreeze/pybreeze_ui/extend_ai_gui/prompt_store.py +56 -0
  12. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/skills/skills_send_gui.py +24 -1
  13. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze.egg-info/PKG-INFO +1 -1
  14. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze.egg-info/SOURCES.txt +3 -0
  15. {pybreeze-1.0.28 → pybreeze-1.0.30}/pyproject.toml +1 -1
  16. pybreeze-1.0.28/pybreeze/pybreeze_ui/extend_ai_gui/code_review/code_review_thread.py +0 -113
  17. pybreeze-1.0.28/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_prompt_editor_widget.py +0 -145
  18. pybreeze-1.0.28/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_editor_widget.py +0 -145
  19. {pybreeze-1.0.28 → pybreeze-1.0.30}/LICENSE +0 -0
  20. {pybreeze-1.0.28 → pybreeze-1.0.30}/README.md +0 -0
  21. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/__init__.py +0 -0
  22. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/__main__.py +0 -0
  23. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/__init__.py +0 -0
  24. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/mail_thunder_extend/__init__.py +0 -0
  25. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/mail_thunder_extend/mail_thunder_setting.py +0 -0
  26. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/__init__.py +0 -0
  27. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/api_testka/__init__.py +0 -0
  28. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/api_testka/api_testka_process.py +0 -0
  29. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/auto_control/__init__.py +0 -0
  30. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/auto_control/auto_control_process.py +0 -0
  31. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/file_automation/__init__.py +0 -0
  32. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/file_automation/file_automation_process.py +0 -0
  33. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/file_runner_process.py +0 -0
  34. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/load_density/__init__.py +0 -0
  35. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/load_density/load_density_process.py +0 -0
  36. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/mail_thunder/__init__.py +0 -0
  37. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/mail_thunder/mail_thunder_process.py +0 -0
  38. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/process_executor_utils.py +0 -0
  39. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/prthinker/__init__.py +0 -0
  40. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/prthinker/prthinker_process.py +0 -0
  41. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/python_task_process_manager.py +0 -0
  42. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/queue_pump.py +0 -0
  43. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/test_pioneer/__init__.py +0 -0
  44. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/test_pioneer/test_pioneer_process_manager.py +0 -0
  45. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/web_runner/__init__.py +0 -0
  46. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/process_executor/web_runner/web_runner_process.py +0 -0
  47. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/prthinker_extend/__init__.py +0 -0
  48. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend/prthinker_extend/prthinker_setting.py +0 -0
  49. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend_multi_language/__init__.py +0 -0
  50. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/extend_multi_language/update_language_dict.py +0 -0
  51. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/__init__.py +0 -0
  52. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/connect_gui/__init__.py +0 -0
  53. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/connect_gui/ssh/__init__.py +0 -0
  54. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_command_widget.py +0 -0
  55. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_file_viewer_widget.py +0 -0
  56. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_host_key_policy.py +0 -0
  57. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_key_loader.py +0 -0
  58. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_login_widget.py +0 -0
  59. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/connect_gui/ssh/ssh_main_widget.py +0 -0
  60. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/connect_gui/url/__init__.py +0 -0
  61. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/connect_gui/url/ai_code_review_gui.py +0 -0
  62. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/diagram_editor/__init__.py +0 -0
  63. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/diagram_editor/diagram_commands.py +0 -0
  64. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/diagram_editor/diagram_editor_widget.py +0 -0
  65. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/diagram_editor/diagram_items.py +0 -0
  66. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/diagram_editor/diagram_mermaid_parser.py +0 -0
  67. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/diagram_editor/diagram_net_utils.py +0 -0
  68. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/diagram_editor/diagram_property_panel.py +0 -0
  69. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/diagram_editor/diagram_scene.py +0 -0
  70. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/diagram_editor/diagram_view.py +0 -0
  71. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/dialog/__init__.py +0 -0
  72. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/dialog/prthinker_setting_dialog.py +0 -0
  73. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/editor_main/__init__.py +0 -0
  74. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/editor_main/file_tree_context_menu.py +0 -0
  75. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/editor_main/main_ui.py +0 -0
  76. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/__init__.py +0 -0
  77. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/code_review/__init__.py +0 -0
  78. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/code_review/cot_code_review_gui.py +0 -0
  79. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/__init__.py +0 -0
  80. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/__init__.py +0 -0
  81. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/code_smell_detector.py +0 -0
  82. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/first_code_review.py +0 -0
  83. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/first_summary_prompt.py +0 -0
  84. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/global_rule.py +0 -0
  85. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/judge.py +0 -0
  86. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/judge_single_review.py +0 -0
  87. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/linter.py +0 -0
  88. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/step_by_step_analysis.py +0 -0
  89. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/total_summary.py +0 -0
  90. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates/__init__.py +0 -0
  91. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates/code_explainer.py +0 -0
  92. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_templates/code_review.py +0 -0
  93. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/extend_ai_gui/skills/__init__.py +0 -0
  94. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/jupyter_lab_gui/__init__.py +0 -0
  95. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/jupyter_lab_gui/jupyter_lab_thread.py +0 -0
  96. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/jupyter_lab_gui/jupyter_lab_widget.py +0 -0
  97. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/__init__.py +0 -0
  98. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/__init__.py +0 -0
  99. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/api_testka_menu/__init__.py +0 -0
  100. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/api_testka_menu/build_api_testka_menu.py +0 -0
  101. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/auto_control_menu/__init__.py +0 -0
  102. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/auto_control_menu/build_autocontrol_menu.py +0 -0
  103. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/automation_file_menu/__init__.py +0 -0
  104. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/automation_file_menu/build_automation_file_menu.py +0 -0
  105. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/automation_menu_factory.py +0 -0
  106. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/load_density_menu/__init__.py +0 -0
  107. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/load_density_menu/build_load_density_menu.py +0 -0
  108. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/mail_thunder_menu/__init__.py +0 -0
  109. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/mail_thunder_menu/build_mail_thunder_menu.py +0 -0
  110. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/prthinker_menu/__init__.py +0 -0
  111. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/prthinker_menu/build_prthinker_menu.py +0 -0
  112. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/test_pioneer_menu/__init__.py +0 -0
  113. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/test_pioneer_menu/build_test_pioneer_menu.py +0 -0
  114. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/web_runner_menu/__init__.py +0 -0
  115. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/automation_menu/web_runner_menu/build_webrunner_menu.py +0 -0
  116. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/build_menubar.py +0 -0
  117. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/extend_jeditor_tab_menu/__init__.py +0 -0
  118. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/extend_jeditor_tab_menu/jupyter_lab_tab.py +0 -0
  119. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/install_menu/__init__.py +0 -0
  120. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/install_menu/automation_menu/__init__.py +0 -0
  121. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/install_menu/automation_menu/build_automation_install_menu.py +0 -0
  122. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/install_menu/install_utils.py +0 -0
  123. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/install_menu/tools_menu/__init__.py +0 -0
  124. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/install_menu/tools_menu/build_tool_install_menu.py +0 -0
  125. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/menu_utils.py +0 -0
  126. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/plugin_menu/__init__.py +0 -0
  127. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/plugin_menu/build_plugin_menu.py +0 -0
  128. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/plugin_menu/build_run_with_menu.py +0 -0
  129. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/tools/__init__.py +0 -0
  130. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/menu/tools/tools_menu.py +0 -0
  131. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/show_code_window/__init__.py +0 -0
  132. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/show_code_window/code_window.py +0 -0
  133. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/syntax/__init__.py +0 -0
  134. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/syntax/syntax_extend.py +0 -0
  135. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/syntax/syntax_keyword.py +0 -0
  136. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/__init__.py +0 -0
  137. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/curl_import_gui.py +0 -0
  138. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/diff_gui.py +0 -0
  139. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/har_import_gui.py +0 -0
  140. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/hash_gui.py +0 -0
  141. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/header_analyzer_gui.py +0 -0
  142. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/http_status_gui.py +0 -0
  143. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/json_format_gui.py +0 -0
  144. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/jwt_decoder_gui.py +0 -0
  145. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/output_actions.py +0 -0
  146. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/query_json_gui.py +0 -0
  147. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/regex_gui.py +0 -0
  148. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/response_inspector_gui.py +0 -0
  149. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/timestamp_gui.py +0 -0
  150. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/tool_tabs.py +0 -0
  151. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/pybreeze_ui/tools_gui/url_builder_gui.py +0 -0
  152. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/__init__.py +0 -0
  153. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/app_dirs.py +0 -0
  154. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/curl_import/__init__.py +0 -0
  155. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/curl_import/curl_parser.py +0 -0
  156. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/curl_import/request_body.py +0 -0
  157. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/curl_import/request_codegen.py +0 -0
  158. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/curl_import/script_templates.py +0 -0
  159. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/diff_tools/__init__.py +0 -0
  160. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/diff_tools/text_diff.py +0 -0
  161. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/exception/__init__.py +0 -0
  162. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/exception/exception_tags.py +0 -0
  163. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/exception/exceptions.py +0 -0
  164. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/file_process/__init__.py +0 -0
  165. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/file_process/get_dir_file_list.py +0 -0
  166. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/har_import/__init__.py +0 -0
  167. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/har_import/har_codegen.py +0 -0
  168. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/har_import/har_parser.py +0 -0
  169. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/hash_tools/__init__.py +0 -0
  170. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/hash_tools/hash_text.py +0 -0
  171. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/header_tools/__init__.py +0 -0
  172. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/header_tools/header_analyzer.py +0 -0
  173. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/header_tools/header_merge.py +0 -0
  174. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/http_reference/__init__.py +0 -0
  175. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/http_reference/status_codes.py +0 -0
  176. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/json_format/__init__.py +0 -0
  177. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/json_format/json_process.py +0 -0
  178. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/jwt_tools/__init__.py +0 -0
  179. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/jwt_tools/jwt_decoder.py +0 -0
  180. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/logging/__init__.py +0 -0
  181. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/logging/logger.py +0 -0
  182. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/manager/__init__.py +0 -0
  183. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/manager/package_manager/__init__.py +0 -0
  184. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/manager/package_manager/package_manager_class.py +0 -0
  185. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/network/__init__.py +0 -0
  186. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/network/http_client.py +0 -0
  187. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/network/url_validation.py +0 -0
  188. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/query_tools/__init__.py +0 -0
  189. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/query_tools/query_convert.py +0 -0
  190. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/regex_tools/__init__.py +0 -0
  191. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/regex_tools/regex_tester.py +0 -0
  192. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/response_inspector/__init__.py +0 -0
  193. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/response_inspector/response_analyzer.py +0 -0
  194. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/subprocess_util.py +0 -0
  195. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/timestamp_tools/__init__.py +0 -0
  196. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/timestamp_tools/timestamp_converter.py +0 -0
  197. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/url_tools/__init__.py +0 -0
  198. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze/utils/url_tools/url_convert.py +0 -0
  199. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze.egg-info/dependency_links.txt +0 -0
  200. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze.egg-info/requires.txt +0 -0
  201. {pybreeze-1.0.28 → pybreeze-1.0.30}/pybreeze.egg-info/top_level.txt +0 -0
  202. {pybreeze-1.0.28 → pybreeze-1.0.30}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pybreeze
3
- Version: 1.0.28
3
+ Version: 1.0.30
4
4
  Summary: IDE for multi automation
5
5
  Author-email: JE-Chen <jechenmailman@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/Intergration-Automation-Testing/AutomationEditor
@@ -134,6 +134,8 @@ pybreeze_english_word_dict = {
134
134
  "prthinker_setting_extra_arguments_label": "Extra command-line arguments",
135
135
  "prthinker_setting_source_path_label": "prthinker source folder",
136
136
  "prthinker_setting_stored_at_label": "Stored at:",
137
+ # Prompt editors — where the edited prompts override the built-in ones from
138
+ "prompt_editor_stored_at_label": "Prompt files (these override the built-in prompts):",
137
139
  "prthinker_choose_source_path_label": "Choose the prthinker source folder",
138
140
  "prthinker_need_source_path_message":
139
141
  "prthinker is installed from source. Choose the folder holding its "
@@ -134,6 +134,8 @@ pybreeze_traditional_chinese_word_dict = {
134
134
  "prthinker_setting_extra_arguments_label": "額外的命令列參數",
135
135
  "prthinker_setting_source_path_label": "prthinker 原始碼資料夾",
136
136
  "prthinker_setting_stored_at_label": "設定檔位置:",
137
+ # Prompt 編輯器 —— 編輯過的 prompt 會覆寫內建版本
138
+ "prompt_editor_stored_at_label": "Prompt 檔案位置(會覆寫內建 prompt):",
137
139
  "prthinker_choose_source_path_label": "選擇 prthinker 原始碼資料夾",
138
140
  "prthinker_need_source_path_message":
139
141
  "prthinker 是從原始碼安裝的。請選擇含有 pyproject.toml 的資料夾,"
@@ -6,8 +6,14 @@ from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.cot_code_review_prompt_t
6
6
  FIRST_CODE_REVIEW_TEMPLATE
7
7
  from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.cot_code_review_prompt_templates.first_summary_prompt import \
8
8
  FIRST_SUMMARY_TEMPLATE
9
+ from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.cot_code_review_prompt_templates.judge import \
10
+ JUDGE_TEMPLATE
11
+ from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.cot_code_review_prompt_templates.judge_single_review import \
12
+ JUDGE_SINGLE_REVIEW_TEMPLATE
9
13
  from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.cot_code_review_prompt_templates.linter import \
10
14
  LINTER_TEMPLATE
15
+ from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.cot_code_review_prompt_templates.step_by_step_analysis import \
16
+ STEP_BY_STEP_ANALYSIS_TEMPLATE
11
17
  from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.cot_code_review_prompt_templates.total_summary import \
12
18
  TOTAL_SUMMARY_TEMPLATE
13
19
  from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.skills_prompt_templates.code_explainer import \
@@ -15,20 +21,30 @@ from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.skills_prompt_templates.
15
21
  from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.skills_prompt_templates.code_review import \
16
22
  CODE_REVIEW_SKILL_TEMPLATE
17
23
 
24
+ # The order the chain runs in. Each step may only quote steps above it, so the
25
+ # order is a dependency order, not a preference: judge_single_review scores the
26
+ # review written just before it, step_by_step_analysis walks the linter and code
27
+ # smell findings, and judge scores the finished summary.
18
28
  COT_TEMPLATE_FILES = [
19
29
  "first_summary_prompt.md",
20
30
  "first_code_review.md",
31
+ "judge_single_review.md",
21
32
  "linter.md",
22
33
  "code_smell_detector.md",
34
+ "step_by_step_analysis.md",
23
35
  "total_summary.md",
36
+ "judge.md",
24
37
  ]
25
38
 
26
39
  COT_TEMPLATE_RELATION = {
27
40
  "first_summary_prompt.md": FIRST_SUMMARY_TEMPLATE,
28
41
  "first_code_review.md": FIRST_CODE_REVIEW_TEMPLATE,
42
+ "judge_single_review.md": JUDGE_SINGLE_REVIEW_TEMPLATE,
29
43
  "linter.md": LINTER_TEMPLATE,
30
44
  "code_smell_detector.md": CODE_SMELL_DETECTOR_TEMPLATE,
45
+ "step_by_step_analysis.md": STEP_BY_STEP_ANALYSIS_TEMPLATE,
31
46
  "total_summary.md": TOTAL_SUMMARY_TEMPLATE,
47
+ "judge.md": JUDGE_TEMPLATE,
32
48
  }
33
49
 
34
50
  SKILLS_TEMPLATE_FILES = [
@@ -0,0 +1,75 @@
1
+ from __future__ import annotations
2
+
3
+ # Worker Thread 負責傳送資料
4
+ import requests
5
+ from PySide6.QtCore import QThread, Signal
6
+ from je_editor import language_wrapper
7
+
8
+ from pybreeze.pybreeze_ui.extend_ai_gui.code_review.cot_chain import (
9
+ CODE_DIFF, STEP_RESULT_KEY, build_prompt
10
+ )
11
+ from pybreeze.utils.logging.logger import pybreeze_logger
12
+ from pybreeze.utils.network.http_client import (
13
+ ResponseTooLargeError, read_capped_text, CONNECT_TIMEOUT,
14
+ )
15
+ from pybreeze.utils.network.url_validation import UnsafeURLError, validate_url
16
+
17
+
18
+ class SenderThread(QThread):
19
+ update_response = Signal(str, str) # (filename, response)
20
+
21
+ def __init__(self, files: list, code: str, url: str):
22
+ super().__init__()
23
+ self.files = files
24
+ self.code = code
25
+ self.url = url
26
+
27
+ def run(self):
28
+ try:
29
+ validate_url(self.url)
30
+ except UnsafeURLError as error:
31
+ pybreeze_logger.error("CoT code review URL rejected: %r", error)
32
+ self.update_response.emit("error", str(error))
33
+ return
34
+ # One session reuses a single TCP/TLS connection across all the
35
+ # sequential per-template POSTs to the same endpoint.
36
+ session = requests.Session()
37
+ try:
38
+ self._run_templates(session, self.code)
39
+ finally:
40
+ session.close()
41
+
42
+ def _run_templates(self, session: requests.Session, code: str) -> None:
43
+ # Answers accumulate here as the chain runs; a later step quotes whichever
44
+ # of them its template asks for. See cot_chain for the wiring.
45
+ results: dict[str, str] = {CODE_DIFF: code}
46
+ for file in self.files:
47
+ # Stop promptly if the widget is closing instead of firing off the
48
+ # remaining per-template POSTs.
49
+ if self.isInterruptionRequested():
50
+ return
51
+ prompt = build_prompt(file, results)
52
+ if prompt is None:
53
+ continue
54
+ reply_text, answered = self._ask(session, file, prompt)
55
+ result_key = STEP_RESULT_KEY.get(file)
56
+ # A failure message is shown but never stored: a later step must not
57
+ # quote "could not send" back to the model as if it were a review.
58
+ if answered and result_key is not None:
59
+ results[result_key] = reply_text
60
+ # 發送訊號更新 UI
61
+ self.update_response.emit(file, reply_text)
62
+
63
+ def _ask(self, session: requests.Session, file: str, prompt: str) -> tuple[str, bool]:
64
+ """Send one step's prompt; return its answer and whether it arrived."""
65
+ try:
66
+ # 傳送到指定 URL(重用 session 連線)
67
+ resp = session.post(
68
+ self.url, json={"prompt": prompt},
69
+ timeout=(CONNECT_TIMEOUT, 60), allow_redirects=False, stream=True,
70
+ )
71
+ return read_capped_text(resp), True
72
+ except (requests.RequestException, ResponseTooLargeError) as error:
73
+ pybreeze_logger.error("CoT code review send failed for %s: %r", file, error)
74
+ word = language_wrapper.language_word_dict
75
+ return f"{word.get('cot_gui_error_sending')} {file} {error}", False
@@ -0,0 +1,100 @@
1
+ """How a chain-of-thought review is wired: what each step quotes from the ones before it.
2
+
3
+ A step is one prompt sent to the review endpoint. Its answer is kept under a short
4
+ result key so a later step can quote it, and that quoting is what decides the order
5
+ the steps run in: a judge cannot score a review that has not been written yet, and
6
+ the step-by-step analysis has nothing to walk through until the linter and the code
7
+ smell detector have reported.
8
+
9
+ Pure logic with no Qt and no network, so the wiring can be tested on its own.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ from collections.abc import Mapping
14
+
15
+ from pybreeze.pybreeze_ui.extend_ai_gui.ai_gui_global_variable import COT_TEMPLATE_RELATION
16
+ from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.cot_code_review_prompt_templates.global_rule import (
17
+ build_global_rule_template
18
+ )
19
+ from pybreeze.pybreeze_ui.extend_ai_gui.prompt_store import load_prompt
20
+ from pybreeze.utils.logging.logger import pybreeze_logger
21
+
22
+ # The key the code under review is seeded into the results under.
23
+ CODE_DIFF = "code_diff"
24
+
25
+ # The result key each step's answer is stored under.
26
+ STEP_RESULT_KEY: dict[str, str] = {
27
+ "first_summary_prompt.md": "first_summary",
28
+ "first_code_review.md": "first_code_review",
29
+ "judge_single_review.md": "judge_single_review",
30
+ "linter.md": "linter",
31
+ "code_smell_detector.md": "code_smell",
32
+ "step_by_step_analysis.md": "step_by_step",
33
+ "total_summary.md": "total_summary",
34
+ "judge.md": "judge",
35
+ }
36
+
37
+ # Each step's template placeholders, and the result key that fills each one.
38
+ STEP_ARGUMENTS: dict[str, dict[str, str]] = {
39
+ "first_summary_prompt.md": {"code_diff": CODE_DIFF},
40
+ "first_code_review.md": {"code_diff": CODE_DIFF},
41
+ # Scores the one review just written, against the code it was written about.
42
+ "judge_single_review.md": {
43
+ "review_comment": "first_code_review",
44
+ "code_diff": CODE_DIFF,
45
+ },
46
+ "linter.md": {"code_diff": CODE_DIFF},
47
+ "code_smell_detector.md": {"code_diff": CODE_DIFF},
48
+ # Walks every lint message and code smell through cause, impact and fix.
49
+ "step_by_step_analysis.md": {
50
+ "linter_result": "linter",
51
+ "code_smell_result": "code_smell",
52
+ },
53
+ "total_summary.md": {
54
+ "first_code_review": "first_code_review",
55
+ "first_summary": "first_summary",
56
+ "linter_result": "linter",
57
+ "code_smell_result": "code_smell",
58
+ "code_diff": CODE_DIFF,
59
+ },
60
+ # Scores the finished summary with the findings it was meant to cover in hand.
61
+ "judge.md": {
62
+ "review_comment": "total_summary",
63
+ "code_smell_detector_messages": "code_smell",
64
+ "linter_messages": "linter",
65
+ "code_diff": CODE_DIFF,
66
+ },
67
+ }
68
+
69
+
70
+ def build_prompt(step: str, results: Mapping[str, str]) -> str | None:
71
+ """Return the prompt for *step*, wrapped in the global review rules.
72
+
73
+ :param step: the template file name the step is known by
74
+ :param results: the answers collected so far, keyed as in
75
+ :data:`STEP_RESULT_KEY`, with the code under review under
76
+ :data:`CODE_DIFF`
77
+ :return: the prompt to send, or ``None`` when *step* is not part of the chain
78
+ """
79
+ built_in = COT_TEMPLATE_RELATION.get(step)
80
+ arguments = STEP_ARGUMENTS.get(step)
81
+ if built_in is None or arguments is None:
82
+ return None
83
+ # A step whose input never ran quotes an empty section rather than the word
84
+ # "None": the model should see that there is nothing there, not read a value.
85
+ filled = {
86
+ placeholder: results.get(key, "")
87
+ for placeholder, key in arguments.items()
88
+ }
89
+ template = load_prompt(step, built_in)
90
+ try:
91
+ body = template.format(**filled)
92
+ except (KeyError, IndexError, ValueError) as error:
93
+ # An edited prompt that names a placeholder the chain cannot fill would
94
+ # otherwise take the whole review down. Fall back to the built-in and say
95
+ # so, rather than failing a step the user cannot debug from the UI.
96
+ pybreeze_logger.error(
97
+ "Edited prompt %s could not be filled in (%r); using the built-in",
98
+ step, error)
99
+ body = built_in.format(**filled)
100
+ return build_global_rule_template(prompt=body)
@@ -0,0 +1,34 @@
1
+ """The editor for the chain-of-thought review prompts."""
2
+ from __future__ import annotations
3
+
4
+ from pybreeze.pybreeze_ui.extend_ai_gui.ai_gui_global_variable import (
5
+ COT_TEMPLATE_FILES, COT_TEMPLATE_RELATION
6
+ )
7
+ from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.prompt_editor_widget import (
8
+ PromptEditorLabels, PromptEditorWidget
9
+ )
10
+
11
+ COT_LABELS = PromptEditorLabels(
12
+ window_title="cot_prompt_editor_window_title",
13
+ edit_group="cot_prompt_editor_groupbox_edit_file_content",
14
+ create_button="cot_prompt_editor_button_create_file",
15
+ save_button="cot_prompt_editor_button_save_file",
16
+ reload_button="cot_prompt_editor_button_reload_file",
17
+ file_not_exist="cot_prompt_editor_file_not_exist",
18
+ info_title="cot_prompt_editor_msgbox_info_title",
19
+ error_title="cot_prompt_editor_msgbox_error_title",
20
+ success_title="cot_prompt_editor_msgbox_success_title",
21
+ file_exists="cot_prompt_editor_msgbox_file_exists",
22
+ file_created="cot_prompt_editor_msgbox_file_created",
23
+ file_saved="cot_prompt_editor_msgbox_file_saved",
24
+ no_file_selected="cot_prompt_editor_msgbox_no_file_selected",
25
+ )
26
+
27
+
28
+ class CoTPromptEditor(PromptEditorWidget):
29
+ """Edit the prompts the chain-of-thought review sends, step by step."""
30
+
31
+ def __init__(self, prompt_files=None, parent=None) -> None:
32
+ super().__init__(
33
+ prompt_files or COT_TEMPLATE_FILES, COT_TEMPLATE_RELATION,
34
+ COT_LABELS, parent)
@@ -0,0 +1,165 @@
1
+ """One prompt editor, shared by the CoT and the Skill template editors.
2
+
3
+ The two differ in exactly two things: which templates they list, and which
4
+ language keys label them. Everything else — loading the selected file, creating
5
+ it from its built-in template, saving, and picking up an external edit — was
6
+ written twice, line for line. It lives here once instead.
7
+
8
+ The language keys arrive as a :class:`PromptEditorLabels` of literal strings
9
+ rather than being built from a prefix, so a key that does not exist can still be
10
+ caught by a test reading the source rather than only at runtime.
11
+ """
12
+ from __future__ import annotations
13
+
14
+ from dataclasses import dataclass
15
+ from pathlib import Path
16
+
17
+ from PySide6.QtCore import QFileSystemWatcher
18
+ from PySide6.QtWidgets import (
19
+ QComboBox, QGroupBox, QHBoxLayout, QLabel, QMessageBox, QPushButton,
20
+ QTextEdit, QVBoxLayout, QWidget
21
+ )
22
+ from je_editor import language_wrapper
23
+
24
+ from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.prompt_file_io import save_prompt_text
25
+ from pybreeze.pybreeze_ui.extend_ai_gui.prompt_store import prompt_dir, prompt_path
26
+
27
+
28
+ @dataclass(frozen=True)
29
+ class PromptEditorLabels:
30
+ """The language keys one editor labels itself with."""
31
+
32
+ window_title: str
33
+ edit_group: str
34
+ create_button: str
35
+ save_button: str
36
+ reload_button: str
37
+ file_not_exist: str
38
+ info_title: str
39
+ error_title: str
40
+ success_title: str
41
+ file_exists: str
42
+ file_created: str
43
+ file_saved: str
44
+ no_file_selected: str
45
+
46
+
47
+ class PromptEditorWidget(QWidget):
48
+ """Edit the prompt files that override the built-in templates."""
49
+
50
+ def __init__(self, files: list[str], templates: dict[str, str],
51
+ labels: PromptEditorLabels, parent=None) -> None:
52
+ """
53
+ :param files: the template file names this editor offers, in order
54
+ :param templates: file name -> the template compiled into the source tree
55
+ :param labels: the language keys this editor is labelled with
56
+ """
57
+ super().__init__(parent)
58
+ self.prompt_files = files
59
+ self.templates = templates
60
+ self._labels = labels
61
+ self.current_file: str | None = None
62
+
63
+ word = language_wrapper.language_word_dict
64
+ self.setWindowTitle(word.get(labels.window_title))
65
+
66
+ self.file_selector = QComboBox()
67
+ self.file_selector.addItems(self.prompt_files)
68
+ self.file_selector.currentIndexChanged.connect(self.load_file_content)
69
+
70
+ self.middle_editor = QTextEdit()
71
+ group = QGroupBox(word.get(labels.edit_group))
72
+ group_layout = QVBoxLayout()
73
+ group_layout.addWidget(self.middle_editor)
74
+ group.setLayout(group_layout)
75
+
76
+ self.reload_button = QPushButton(word.get(labels.reload_button))
77
+ self.reload_button.clicked.connect(
78
+ lambda: self.load_file_content(self.file_selector.currentIndex()))
79
+ self.save_button = QPushButton(word.get(labels.save_button))
80
+ self.save_button.clicked.connect(self.save_file)
81
+ self.create_button = QPushButton(word.get(labels.create_button))
82
+ self.create_button.clicked.connect(self.create_file)
83
+
84
+ bottom_layout = QHBoxLayout()
85
+ bottom_layout.addWidget(self.file_selector)
86
+ bottom_layout.addStretch()
87
+ for button in (self.reload_button, self.save_button, self.create_button):
88
+ bottom_layout.addWidget(button)
89
+
90
+ # 這些檔案覆寫實際送出的 prompt,位置要讓人找得到
91
+ # These files override the prompt that is sent, so say where they are
92
+ where = QLabel(f"{word.get('prompt_editor_stored_at_label')} {prompt_dir()}")
93
+ where.setWordWrap(True)
94
+
95
+ main_layout = QVBoxLayout(self)
96
+ main_layout.addWidget(group)
97
+ main_layout.addWidget(where)
98
+ main_layout.addLayout(bottom_layout)
99
+
100
+ # 檔案監控器:外部改動即時反映 / Pick up edits made outside the editor
101
+ self.watcher = QFileSystemWatcher(
102
+ [str(prompt_path(name)) for name in self.prompt_files])
103
+ self.watcher.fileChanged.connect(self.on_file_changed)
104
+
105
+ if self.prompt_files:
106
+ self.load_file_content(0)
107
+
108
+ def load_file_content(self, index: int) -> None:
109
+ """載入選擇的檔案內容 / Show the selected file, or say it is not there yet."""
110
+ name = self.prompt_files[index]
111
+ self.current_file = str(prompt_path(name))
112
+ path = Path(self.current_file)
113
+ if path.is_file():
114
+ self.middle_editor.setPlainText(path.read_text(encoding="utf-8"))
115
+ return
116
+ self.middle_editor.setPlainText(
117
+ language_wrapper.language_word_dict.get(
118
+ self._labels.file_not_exist).format(filename=name))
119
+
120
+ def create_file(self) -> None:
121
+ """用內建模板建立目前選擇的檔案 / Create the selected file from its built-in template."""
122
+ word = language_wrapper.language_word_dict
123
+ if self.current_file is None:
124
+ return
125
+ if Path(self.current_file).is_file():
126
+ QMessageBox.information(
127
+ self, word.get(self._labels.info_title),
128
+ word.get(self._labels.file_exists).format(filename=self.current_file))
129
+ return
130
+
131
+ content = self.templates.get(Path(self.current_file).name, "")
132
+ if not save_prompt_text(
133
+ self, self.current_file, content, word.get(self._labels.error_title)):
134
+ return
135
+
136
+ # Only now does the file exist, so only now can it be watched for the
137
+ # external edits this editor promises to pick up.
138
+ self.watcher.addPath(self.current_file)
139
+ QMessageBox.information(
140
+ self, word.get(self._labels.success_title),
141
+ word.get(self._labels.file_created).format(filename=self.current_file))
142
+ self.load_file_content(self.file_selector.currentIndex())
143
+
144
+ def on_file_changed(self, path: str) -> None:
145
+ """外部改動時重新載入 / Reload when the file changes underneath us."""
146
+ if path == self.current_file:
147
+ self.load_file_content(self.file_selector.currentIndex())
148
+
149
+ def save_file(self) -> None:
150
+ """把編輯區內容存回檔案 / Write the edit area back to the file."""
151
+ word = language_wrapper.language_word_dict
152
+ if self.current_file is None:
153
+ QMessageBox.warning(
154
+ self, word.get(self._labels.error_title),
155
+ word.get(self._labels.no_file_selected))
156
+ return
157
+
158
+ if not save_prompt_text(
159
+ self, self.current_file, self.middle_editor.toPlainText(),
160
+ word.get(self._labels.error_title)):
161
+ return
162
+ self.watcher.addPath(self.current_file)
163
+ QMessageBox.information(
164
+ self, word.get(self._labels.success_title),
165
+ word.get(self._labels.file_saved).format(filename=self.current_file))
@@ -6,6 +6,8 @@ a user-facing dialog instead of an uncaught traceback.
6
6
  """
7
7
  from __future__ import annotations
8
8
 
9
+ from pathlib import Path
10
+
9
11
  from PySide6.QtWidgets import QMessageBox, QWidget
10
12
 
11
13
  from pybreeze.utils.logging.logger import pybreeze_logger
@@ -18,6 +20,9 @@ def save_prompt_text(parent: QWidget, path: str, content: str, error_title: str)
18
20
  caller can skip its success message).
19
21
  """
20
22
  try:
23
+ # The directory is made here rather than on every read, so a session that
24
+ # only looks at the built-in prompts leaves nothing behind.
25
+ Path(path).parent.mkdir(parents=True, exist_ok=True)
21
26
  with open(path, "w", encoding="utf-8") as file_handle:
22
27
  file_handle.write(content)
23
28
  return True
@@ -0,0 +1,34 @@
1
+ """The editor for the reusable skill prompts."""
2
+ from __future__ import annotations
3
+
4
+ from pybreeze.pybreeze_ui.extend_ai_gui.ai_gui_global_variable import (
5
+ SKILLS_TEMPLATE_FILES, SKILLS_TEMPLATE_RELATION
6
+ )
7
+ from pybreeze.pybreeze_ui.extend_ai_gui.prompt_edit_gui.prompt_editor_widget import (
8
+ PromptEditorLabels, PromptEditorWidget
9
+ )
10
+
11
+ SKILL_LABELS = PromptEditorLabels(
12
+ window_title="skill_prompt_editor_window_title",
13
+ edit_group="skill_prompt_editor_groupbox_edit_file_content",
14
+ create_button="skill_prompt_editor_button_create_file",
15
+ save_button="skill_prompt_editor_button_save_file",
16
+ reload_button="skill_prompt_editor_button_reload_file",
17
+ file_not_exist="skill_prompt_editor_file_not_exist",
18
+ info_title="skill_prompt_editor_msgbox_info_title",
19
+ error_title="skill_prompt_editor_msgbox_error_title",
20
+ success_title="skill_prompt_editor_msgbox_success_title",
21
+ file_exists="skill_prompt_editor_msgbox_file_exists",
22
+ file_created="skill_prompt_editor_msgbox_file_created",
23
+ file_saved="skill_prompt_editor_msgbox_file_saved",
24
+ no_file_selected="skill_prompt_editor_msgbox_no_file_selected",
25
+ )
26
+
27
+
28
+ class SkillPromptEditor(PromptEditorWidget):
29
+ """Edit the reusable skill prompts the send window offers."""
30
+
31
+ def __init__(self, skill_files=None, parent=None) -> None:
32
+ super().__init__(
33
+ skill_files or SKILLS_TEMPLATE_FILES, SKILLS_TEMPLATE_RELATION,
34
+ SKILL_LABELS, parent)
@@ -0,0 +1,56 @@
1
+ """Where the editable prompt templates live, and how one is resolved.
2
+
3
+ Every template ships as a constant in the source tree and may be overridden by a
4
+ file the user edits. The file wins when it has content, so editing a prompt in the
5
+ editor changes what the review actually sends — which is the only reason the
6
+ editor is there.
7
+
8
+ The files sit under the user's own directory rather than the working one, so the
9
+ prompts someone has written are the same whichever folder the IDE was started
10
+ from, matching where the SSH known hosts and the prthinker settings are kept.
11
+ """
12
+ from __future__ import annotations
13
+
14
+ from pathlib import Path
15
+
16
+ from pybreeze.utils.app_dirs import pybreeze_data_dir
17
+ from pybreeze.utils.logging.logger import pybreeze_logger
18
+
19
+ _PROMPT_DIR_NAME = "prompts"
20
+
21
+
22
+ def prompt_dir() -> Path:
23
+ """Return the directory the editable prompt files live in.
24
+
25
+ Reading and naming a prompt must not create anything: opening the editor to
26
+ look at a built-in prompt should leave no directory behind. ``save_prompt_text``
27
+ makes the directory when there is finally something to put in it.
28
+ """
29
+ return pybreeze_data_dir() / _PROMPT_DIR_NAME
30
+
31
+
32
+ def prompt_path(name: str) -> Path:
33
+ """Return the file the prompt called *name* is edited in."""
34
+ return prompt_dir() / name
35
+
36
+
37
+ def load_prompt(name: str, default: str) -> str:
38
+ """Return the edited prompt *name*, or the built-in *default*.
39
+
40
+ A file that is missing, empty or unreadable falls back to the built-in: an
41
+ override that says nothing must not leave a review step with nothing to ask,
42
+ and a file that cannot be read must not stop the review.
43
+
44
+ :param name: the prompt's file name, e.g. ``linter.md``
45
+ :param default: the template compiled into the source tree
46
+ :return: the prompt text to use
47
+ """
48
+ path = prompt_path(name)
49
+ if not path.is_file():
50
+ return default
51
+ try:
52
+ edited = path.read_text(encoding="utf-8")
53
+ except OSError as error:
54
+ pybreeze_logger.error("Prompt %s could not be read: %r", name, error)
55
+ return default
56
+ return edited if edited.strip() else default
@@ -8,7 +8,10 @@ from PySide6.QtWidgets import (
8
8
  from PySide6.QtCore import QThread, Signal
9
9
  from je_editor import language_wrapper
10
10
 
11
- from pybreeze.pybreeze_ui.extend_ai_gui.ai_gui_global_variable import SKILLS_TEMPLATE_FILES
11
+ from pybreeze.pybreeze_ui.extend_ai_gui.ai_gui_global_variable import (
12
+ SKILLS_TEMPLATE_FILES, SKILLS_TEMPLATE_RELATION
13
+ )
14
+ from pybreeze.pybreeze_ui.extend_ai_gui.prompt_store import load_prompt
12
15
  from pybreeze.utils.logging.logger import pybreeze_logger
13
16
  from pybreeze.utils.network.http_client import (
14
17
  ResponseTooLargeError, read_capped_text, CONNECT_TIMEOUT, truncate_for_display,
@@ -80,6 +83,7 @@ class SkillsSendGUI(QWidget):
80
83
  self.prompt_select_label = QLabel(language_wrapper.language_word_dict.get("skills_prompt_select_label"))
81
84
  self.prompt_select = QComboBox()
82
85
  self.prompt_select.addItems(SKILLS_TEMPLATE_FILES)
86
+ self.prompt_select.currentTextChanged.connect(self.load_selected_prompt)
83
87
  layout.addWidget(self.prompt_select_label)
84
88
  layout.addWidget(self.prompt_select)
85
89
 
@@ -104,6 +108,25 @@ class SkillsSendGUI(QWidget):
104
108
  self.setLayout(layout)
105
109
 
106
110
  self.thread = None # 保存執行緒
111
+ # 開啟時就把選到的那個模板載進來,選單才不是擺著好看
112
+ # Load the selected template on open, so the selector does something
113
+ self.load_selected_prompt(self.prompt_select.currentText())
114
+
115
+ def load_selected_prompt(self, name: str) -> None:
116
+ """
117
+ 把選到的 skill 模板載進編輯區
118
+ Put the selected skill template in the edit area.
119
+
120
+ 以編輯過的檔案為準,沒有就用內建的;載進來以後仍然可以改,送出的是編輯區的內容。
121
+ The edited file wins over the built-in one. What lands here stays
122
+ editable: what is sent is whatever the edit area holds.
123
+
124
+ :param name: 模板檔名 / the template's file name
125
+ """
126
+ built_in = SKILLS_TEMPLATE_RELATION.get(name)
127
+ if built_in is None:
128
+ return
129
+ self.prompt_input.setPlainText(load_prompt(name, built_in))
107
130
 
108
131
  def send_prompt(self):
109
132
  # Ignore re-submits while a request is in flight: reassigning self.thread
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pybreeze
3
- Version: 1.0.28
3
+ Version: 1.0.30
4
4
  Summary: IDE for multi automation
5
5
  Author-email: JE-Chen <jechenmailman@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/Intergration-Automation-Testing/AutomationEditor
@@ -66,11 +66,14 @@ pybreeze/pybreeze_ui/editor_main/file_tree_context_menu.py
66
66
  pybreeze/pybreeze_ui/editor_main/main_ui.py
67
67
  pybreeze/pybreeze_ui/extend_ai_gui/__init__.py
68
68
  pybreeze/pybreeze_ui/extend_ai_gui/ai_gui_global_variable.py
69
+ pybreeze/pybreeze_ui/extend_ai_gui/prompt_store.py
69
70
  pybreeze/pybreeze_ui/extend_ai_gui/code_review/__init__.py
70
71
  pybreeze/pybreeze_ui/extend_ai_gui/code_review/code_review_thread.py
72
+ pybreeze/pybreeze_ui/extend_ai_gui/code_review/cot_chain.py
71
73
  pybreeze/pybreeze_ui/extend_ai_gui/code_review/cot_code_review_gui.py
72
74
  pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/__init__.py
73
75
  pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_prompt_editor_widget.py
76
+ pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/prompt_editor_widget.py
74
77
  pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/prompt_file_io.py
75
78
  pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/skills_prompt_editor_widget.py
76
79
  pybreeze/pybreeze_ui/extend_ai_gui/prompt_edit_gui/cot_code_review_prompt_templates/__init__.py
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "pybreeze"
9
- version = "1.0.28"
9
+ version = "1.0.30"
10
10
  authors = [
11
11
  { name = "JE-Chen", email = "jechenmailman@gmail.com" },
12
12
  ]