Compare commits

...

289 Commits
v0.2 ... v0.22

Author SHA1 Message Date
Tal
e5bbb701d3 Update README.md 2024-05-19 13:03:30 +03:00
Tal
7779038e2a Merge pull request #912 from Codium-ai/tr/show_config
Tr/show config
2024-05-19 12:37:58 +03:00
c3dca2ef5a Refactor model selection logic for PR tools and update turbo model to gpt-4o 2024-05-19 12:37:31 +03:00
985b4f05cf Refactor model selection logic for PR tools and update turbo model to gpt-4o 2024-05-19 12:37:06 +03:00
8921d9eb0e Refactor model selection logic for PR tools and update turbo model to gpt-4o 2024-05-19 12:35:19 +03:00
2880e48860 Refactor model selection logic for PR tools and update turbo model to gpt-4o 2024-05-19 12:29:06 +03:00
9b56c83c1d APP_NAME 2024-05-19 12:18:22 +03:00
Tal
2369b8da69 Merge pull request #911 from Codium-ai/tr/show_config
Update configuration_options.md to include tip on showing relevant co…
2024-05-19 08:22:07 +03:00
dcd188193b Update configuration_options.md to include tip on showing relevant configurations 2024-05-19 08:20:15 +03:00
Tal
89819b302b Merge pull request #910 from Codium-ai/tr/show_config
Tr/show config
2024-05-19 08:06:20 +03:00
3432d377c7 Update configuration_options.md to include tip on showing relevant configurations 2024-05-18 13:14:16 +03:00
ea4ee1adbc Add show_relevant_configurations function and integrate it across tools to output relevant configurations if enabled 2024-05-18 13:09:50 +03:00
Tal
f9af9e4a91 Update pr_code_suggestions_prompts.toml 2024-05-16 21:59:00 +03:00
Tal
3b3e885b76 Merge pull request #906 from Codium-ai/tr/self_reflect
Tr/self reflect
2024-05-16 21:57:32 +03:00
46e934772c Rename "Custom Suggestions" feature to "Custom Prompt" across documentation, README, and tool references 2024-05-16 21:55:02 +03:00
cc08394e51 Refine field descriptions in pr_code_suggestions_prompts.toml and comment out default scoring error log in pr_code_suggestions.py 2024-05-16 21:49:06 +03:00
Tal
2b4eac2123 Merge pull request #905 from Codium-ai/tr/self_reflect
Add roadmap section to Chrome Extension documentation with visual pre…
2024-05-16 10:57:02 +03:00
570f7d6dcf Add roadmap section to Chrome Extension documentation with visual preview 2024-05-16 10:55:51 +03:00
Tal
188d092524 Merge pull request #904 from Codium-ai/tr/self_reflect
Add documentation for PR-Agent Chrome Extension and update mkdocs.yml…
2024-05-16 09:18:34 +03:00
8599c0fed4 Add documentation for PR-Agent Chrome Extension and update mkdocs.yml to include new section 2024-05-16 09:17:26 +03:00
0ab19b84b2 Add documentation for PR-Agent Chrome Extension and update mkdocs.yml to include new section 2024-05-16 09:12:55 +03:00
Tal
fec583e45e Merge pull request #903 from Codium-ai/mrT23-patch-3
Update README.md
2024-05-15 10:37:53 +03:00
Tal
589b865db5 Update README.md 2024-05-15 10:31:57 +03:00
Tal
be701aa868 Merge pull request #902 from Codium-ai/tr/self_reflect
Refactor Azure DevOps provider to use PR iterations for change detect…
2024-05-15 09:22:14 +03:00
4231a84e7a Refactor Azure DevOps provider to use PR iterations for change detection, improving accuracy of diff file identification 2024-05-15 09:15:12 +03:00
e56320540b Refactor Azure DevOps provider to use PR iterations for change detection, improving accuracy of diff file identification 2024-05-15 09:05:01 +03:00
e4565f7106 Refactor Azure DevOps provider to use PR iterations for change detection, improving accuracy of diff file identification 2024-05-14 21:43:14 +03:00
Tal
b4458ffede Merge pull request #901 from KennyDizi/main
Add new GPT-4o models and update tiktoken to 0.7.0
2024-05-14 09:25:24 +03:00
36ad8935ad Add gpt-4o models 2024-05-14 08:24:34 +07:00
9dd2520dbd Update tiktoken to 0.7.0 2024-05-14 08:21:41 +07:00
Tal
e6708fcb7b Merge pull request #898 from Codium-ai/tr/self_reflect
Tr/self reflect
2024-05-13 18:22:44 +03:00
05876afc02 Refactor pr_code_suggestions logic and update prompts for clarity and consistency 2024-05-13 18:21:31 +03:00
f3eb74d718 Refactor pr_code_suggestions logic and update prompts for clarity and consistency 2024-05-13 18:18:17 +03:00
b0aac4ec5d Refactor pr_code_suggestions logic and update prompts for clarity and consistency 2024-05-13 18:13:37 +03:00
95c7b3f55c Refactor pr_code_suggestions logic and update prompts for clarity and consistency 2024-05-13 18:03:13 +03:00
Tal
efd906ccf1 Update .pr_agent.toml 2024-05-13 17:52:09 +03:00
Tal
5fed21ce37 Update README.md 2024-05-13 09:44:59 +03:00
Tal
853cfb3fc9 Merge pull request #897 from Codium-ai/tr/self_reflect
Tr/self reflect
2024-05-13 09:28:58 +03:00
6c0837491c Update README.md to include info on filtering suggestions by score threshold 2024-05-13 09:21:55 +03:00
fbacc7c765 artifact 2024-05-13 09:19:08 +03:00
Tal
e69b798aa1 Merge pull request #895 from Codium-ai/tr/self_reflect
self-reflection documentation
2024-05-12 16:23:07 +03:00
61ba015a55 artifact 2024-05-12 16:22:40 +03:00
4f6490b17c Integrate self-reflection feature in PR-Agent, enhancing code suggestions with scoring and sorting, and update documentation accordingly 2024-05-12 16:17:47 +03:00
Tal
9dfc263e2e Merge pull request #894 from Codium-ai/tr/self_reflect
Tr/self reflect
2024-05-12 16:01:08 +03:00
d348cffbae Enhance error handling and logging in pr_code_suggestions with default scores and contextualized self_reflection 2024-05-12 15:52:59 +03:00
c04ab933cd s 2024-05-12 15:04:36 +03:00
a55fa753b9 s 2024-05-12 14:54:35 +03:00
8e0435d9a0 s 2024-05-12 14:40:25 +03:00
39c0733d6f s 2024-05-12 14:00:30 +03:00
a588e9f2bb s 2024-05-12 13:55:12 +03:00
7627e651ea s 2024-05-12 13:50:10 +03:00
1ebc20b761 self_reflect 2024-05-12 13:49:28 +03:00
Tal
38058ea714 Merge pull request #893 from Codium-ai/tr/readme3
Tr/readme3
2024-05-08 15:43:32 +03:00
c92c26448f s 2024-05-08 15:42:00 +03:00
38051f79b7 s 2024-05-08 14:38:28 +03:00
738eb055ff s 2024-05-08 14:28:38 +03:00
Tal
5d8d178a60 Merge pull request #892 from Codium-ai/mrT23-patch-3
Update configuration_options.md
2024-05-08 13:55:27 +03:00
Tal
e8f4a45774 Update configuration_options.md 2024-05-08 13:54:31 +03:00
Tal
aa60c7d701 Merge pull request #890 from Codium-ai/tr/branding
privacy
2024-05-05 16:15:04 +03:00
4645cd7cf9 privacy 2024-05-05 16:13:28 +03:00
edb230c993 privacy 2024-05-05 16:11:03 +03:00
7bb1917be7 privacy 2024-05-05 16:09:07 +03:00
Tal
d360fb72cb Merge pull request #889 from Codium-ai/tr/branding
privacy policy for chrome extension
2024-05-05 16:03:00 +03:00
253f77f4d9 privacy 2024-05-05 16:01:07 +03:00
Tal
cac450098a Merge pull request #887 from Codium-ai/tr/branding
Tr/branding
2024-05-05 14:00:17 +03:00
097637d7c0 toolbar emojis in pr-agent feedbacks 2024-05-05 13:48:45 +03:00
e4157d2efc toolbar emojis in pr-agent feedbacks 2024-05-05 13:36:34 +03:00
34ad5f2aa2 toolbar emojis in pr-agent feedbacks 2024-05-05 13:33:54 +03:00
Tal
3c76230f61 Update README.md 2024-05-03 14:52:19 +03:00
Tal
92cde2ef99 Update README.md 2024-05-03 08:32:39 +03:00
0b10f88b84 toolbar 2024-05-02 21:08:12 +03:00
Tal
3dbe1bbc35 Merge pull request #880 from tacascer/new-35-models
chore: update GPT3.5 models
2024-04-24 08:52:12 +03:00
2e34436589 chore: update GPT3.5 models 2024-04-22 20:25:32 -04:00
Tal
fae6cab2a7 Merge pull request #877 from randy-tsukemen/support-groq-llama3
Add Groq Llama3 support
2024-04-22 11:41:12 +03:00
Tal
19f239ae3d Merge pull request #876 from randy-tsukemen/fix-duplication
Fix duplicate assignment of replicate_key in LiteLLMAIHandler
2024-04-21 10:55:01 +03:00
d457fa2b9f Add Groq API key configuration to .secrets_template.toml 2024-04-21 15:22:40 +09:00
d430604dfe Add Groq Llama3 model configuration instructions to usage guide 2024-04-21 15:22:19 +09:00
0a53f09a7f Add GROQ.KEY support in LiteLLMAIHandler 2024-04-21 15:21:45 +09:00
7a9e73702d Fix duplicate assignment of replicate_key in LiteLLMAIHandler 2024-04-21 14:47:25 +09:00
Tal
e429c5d012 Merge pull request #873 from Codium-ai/tr/readme
docs: Add option to disable automatic CI feedback in configuration
2024-04-18 16:33:21 +03:00
1c8aeb2b64 docs: Add option to disable automatic CI feedback in configuration 2024-04-18 16:31:41 +03:00
Tal
4d6126d2c0 Merge pull request #872 from Codium-ai/tr/readme
## Example usage
2024-04-18 10:11:39 +03:00
a9d30c1d10 Remember 2024-04-18 10:11:19 +03:00
ea4d4ab618 ## Example usage 2024-04-18 10:04:38 +03:00
Tal
3088c58d5f Merge pull request #871 from Codium-ai/tr/readme
Tr/readme
2024-04-18 09:27:51 +03:00
0f99db65a9 docs 2024-04-18 09:10:14 +03:00
f913f02ea6 docs 2024-04-18 08:53:43 +03:00
7563af08a0 docs 2024-04-18 08:44:08 +03:00
ad96326832 not 2024-04-18 07:53:37 +03:00
Tal
003d5728e0 Merge pull request #870 from Codium-ai/tr/readme
Replace `summarize_mode` with `commitable_code_suggestions_mode` in p…
2024-04-18 07:32:32 +03:00
8242b10d8e Replace summarize_mode with commitable_code_suggestions_mode in pr_code_suggestions_prompts.toml to enhance PR suggestion mechanism 2024-04-18 07:31:33 +03:00
Tal
1c296127bd Merge pull request #865 from Codium-ai/tr/readme
Tr/readme
2024-04-17 21:06:32 +03:00
2f4e40860d Replace keep_original_user_title with generate_ai_title for PR description customization and update documentation accordingly 2024-04-17 16:29:12 +03:00
b076c33351 commitable_code_suggestions 2024-04-17 15:32:45 +03:00
e2e0bea8fd num_code_suggestions 2024-04-17 09:13:53 +03:00
e878dcb6b1 Example usage 2024-04-17 09:12:49 +03:00
Tal
b8bcaf86f2 Merge pull request #864 from Codium-ai/tr/readme
Example usage
2024-04-17 09:05:18 +03:00
6c78f4fd88 Example usage 2024-04-17 09:02:54 +03:00
Tal
a134a8bf6d Merge pull request #863 from Codium-ai/add-repo-url-to-docs
Add repo url to docs
2024-04-15 20:41:41 +03:00
32fd03bd55 Add repository URL to MkDocs configuration 2024-04-15 13:42:36 +03:00
d5262f24ca add name + github icon 2024-04-15 13:37:50 +03:00
fe231929ae Update mkdocs.yml to include site description and rename site 2024-04-15 13:33:22 +03:00
1481796d6a Add GitHub repository URL to MkDocs configuration 2024-04-15 13:32:05 +03:00
Tal
9274cd730d Merge pull request #862 from Codium-ai/tr/image
ask
2024-04-15 10:14:21 +03:00
93d153bae1 ask 2024-04-15 10:12:19 +03:00
Tal
50736447fb Merge pull request #860 from Codium-ai/tr/image
ask
2024-04-14 14:48:43 +03:00
8168ce0c8e ask 2024-04-14 14:45:15 +03:00
Tal
a8d2fca4a3 Merge pull request #859 from Codium-ai/tr/image
Tr/image
2024-04-14 14:14:06 +03:00
44eb0b4f23 ask 2024-04-14 14:12:48 +03:00
506e3007c4 ask 2024-04-14 14:11:04 +03:00
92ef2b4464 ask 2024-04-14 14:09:58 +03:00
86e64501df ask 2024-04-14 12:43:26 +03:00
f0230fce79 gpt-4-turbo-2024-04-09 2024-04-14 12:37:54 +03:00
4683a29819 s 2024-04-14 12:34:14 +03:00
8f0f08006f s 2024-04-14 12:00:19 +03:00
a4680ded93 protections 2024-04-12 20:32:47 +03:00
Tal
654f88b98a Merge pull request #858 from pkvach/handle-missing-openai-key
Handle OPENAI_KEY not set error in github_action_runner.py
2024-04-12 18:30:15 +03:00
4c83bf695d Handle OPENAI_KEY not set error in github_action_runner.py
Fixes https://github.com/Codium-ai/pr-agent/issues/855
2024-04-12 10:50:00 +03:00
Tal
af8ca7d1a4 Merge pull request #853 from idubnori/feature/gha-outputs-1
feat: set review data to github actions output
2024-04-11 16:34:49 +03:00
9e4ffd824c Merge branch 'main' into feature/gha-outputs-1 2024-04-10 23:27:44 +09:00
aef1c6ecde docs: add feature spec and config 2024-04-10 23:04:29 +09:00
5e5ead98de test: rename & add error case 2024-04-10 22:36:15 +09:00
ae633b3cea refine: github_action_output 2024-04-10 22:30:16 +09:00
97dcb34d77 clean: rename to github_action_output 2024-04-10 22:16:09 +09:00
Tal
f0c5aec0e4 Merge pull request #854 from riya-amemiya/riya-amemiya/add_model
add support for gpt-4-turbo model
2024-04-10 09:20:53 +03:00
108b1afa0e add new models 2024-04-10 14:44:38 +09:00
Tal
4a69ebe816 Merge pull request #851 from phuongvietnamlab/hotfix/is_valid_file
Failed to review PR: name 'is_valid_file' is not defined
2024-04-10 08:21:43 +03:00
3412095d81 chore: change default to true, if use in github actions 2024-04-10 09:18:21 +09:00
45176ab893 test: add config not set case 2024-04-10 09:17:29 +09:00
75c4befadf feat: set review data to github actions output 2024-04-10 01:02:05 +09:00
0257b619ff Failed to review PR: name 'is_valid_file' is not defined 2024-04-09 15:47:54 +07:00
Tal
7e664184be Merge pull request #848 from Codium-ai/tr/readme
Tr/readme
2024-04-08 15:50:19 +03:00
8a5b01b465 empty calc_pr_statistics 2024-04-08 14:49:00 +03:00
84d8f78d0c publish_output 2024-04-08 14:00:41 +03:00
Tal
c1c11e6c77 Merge pull request #846 from Codium-ai/tr/readme
readme
2024-04-08 09:14:54 +03:00
a543d7ed1a readme 2024-04-08 09:12:50 +03:00
Tal
236d7c44e2 Merge pull request #845 from Codium-ai/change-docs-readme
Update docs readme
2024-04-08 09:06:23 +03:00
09f76f45ef Update docs readme 2024-04-08 08:18:33 +03:00
Tal
61388f6d28 Merge pull request #844 from Codium-ai/tr/readme
readme
2024-04-07 17:05:09 +03:00
a5a68c2a73 readme 2024-04-07 17:02:37 +03:00
2be0e9108e readme 2024-04-07 17:00:40 +03:00
aa2121a48d readme 2024-04-07 16:28:30 +03:00
Tal
4841f0db7c Merge pull request #843 from network-charles/network-charles-patch-1
Fix Broken URL in README.md
2024-04-07 13:03:10 +03:00
dc14b87657 Update README.md 2024-04-07 10:06:05 +01:00
Tal
7b4d833e06 Merge pull request #842 from Codium-ai/tr/readme
readme
2024-04-07 11:53:25 +03:00
68f29a41ef readme 2024-04-07 11:52:42 +03:00
d6b037a63a readme 2024-04-07 11:51:06 +03:00
45eefaa4f0 readme 2024-04-07 11:04:23 +03:00
f3b4695617 readme 2024-04-07 10:43:56 +03:00
Tal
dbcbe52d3e Merge pull request #841 from Codium-ai/tr/readme
readme
2024-04-07 09:41:21 +03:00
60fd1c67fa readme 2024-04-07 09:35:41 +03:00
d9efc441df readme 2024-04-07 09:28:22 +03:00
Tal
cb13740166 Merge pull request #840 from Codium-ai/tr/readme
readme
2024-04-07 09:11:19 +03:00
4dc160bc16 readme 2024-04-07 09:08:40 +03:00
Tal
d9b4481701 Merge pull request #839 from Codium-ai/mrT23-patch-1
Update additional_configurations.md
2024-04-05 17:24:45 +03:00
Tal
bbd302360f Update additional_configurations.md 2024-04-05 17:22:54 +03:00
877aeffbb3 Update describe.md 2024-04-03 14:59:53 +03:00
d7b19af117 Update README.md 2024-04-03 14:53:56 +03:00
Tal
7bc4f3a1c1 Merge pull request #838 from Codium-ai/tr/single_encoder
TokenEncoder
2024-04-03 08:49:49 +03:00
9c3673209d TokenEncoder 2024-04-03 08:42:50 +03:00
Tal
a13c6e964b Merge pull request #837 from Codium-ai/tr/persistent_describe
feat: add persistent comment option for PR descriptions
2024-04-02 17:59:17 +03:00
9614f619e8 feat: add persistent comment option for PR descriptions 2024-04-02 17:54:37 +03:00
3ebb72e3f1 feat: add persistent comment option for PR descriptions 2024-04-02 17:52:34 +03:00
Tal
dfe8301dcd Merge pull request #836 from gregoryboue/main
feat: allows ollama usage
2024-04-02 16:30:54 +03:00
501b059575 feat: allows ollama usage
Fix https://github.com/Codium-ai/pr-agent/issues/657
2024-04-02 11:01:45 +02:00
Tal
27cdd419e5 Update index.md 2024-04-01 18:56:36 +03:00
Tal
3d86430f18 Update automations_and_usage.md 2024-04-01 18:46:08 +03:00
b7237c113b Merge pull request #834 from Codium-ai/analytics
analytics
2024-04-01 10:19:17 +03:00
a53ba4596e fix custom analytics 2024-04-01 10:03:36 +03:00
b86b37e6a2 analytics 2024-04-01 09:54:59 +03:00
Tal
4391ac4d4d Merge pull request #833 from Codium-ai/tr/help
docs: Add "Improve Component" tool documentation and update related g…
2024-03-31 12:18:20 +03:00
ce47adf986 C# 2024-03-31 12:15:29 +03:00
8bda365636 docs: Add "Improve Component" tool documentation and update related guides 2024-03-31 12:13:25 +03:00
Tal
30bb2f3fc9 Merge pull request #832 from Codium-ai/tr/help
refine help
2024-03-31 11:44:29 +03:00
c3b3651769 refine help 2024-03-31 11:43:00 +03:00
Tal
949808d0d2 Merge pull request #831 from Codium-ai/tr/readme4
docs: Refine project description and reorganize documentation links i…
2024-03-29 13:43:48 +03:00
7e84acc63c docs: Refine project description and reorganize documentation links in README 2024-03-29 13:34:23 +03:00
aae6869964 docs: Update PR-Agent usage guide 2024-03-28 09:37:29 +02:00
79bdb9a69f bugfix: validate output publishing with progress condition in pr_code_suggestions 2024-03-27 19:56:27 +02:00
Tal
a86913aa7f Merge pull request #828 from idubnori/work/fix-827
Improve trigger condition in github actions
2024-03-27 19:07:53 +02:00
020a29ebb8 docs: optimize condition of github actions 2024-03-27 20:53:46 +09:00
Tal
a8bee89ae9 Update custom.css 2024-03-27 13:00:16 +02:00
Tal
d0dc2af918 Merge pull request #829 from Codium-ai/mrT23-patch-7
Update github.md
2024-03-27 12:42:07 +02:00
Tal
82d9c77489 Update github.md 2024-03-27 12:40:47 +02:00
Tal
c42f2d17e7 Merge pull request #825 from Codium-ai/improve-docs-images
Refactor markdown image syntax and enhance documentation presentation
2024-03-27 12:36:30 +02:00
Tal
cd4deefbf8 Merge pull request #826 from s1moe2/fix/issue-824
fix: missing requirements.txt on lambda dockerfile
2024-03-27 12:32:23 +02:00
493f73f1ce chore: add logging the reason not execute 2024-03-27 12:03:27 +09:00
fa889fbb06 docs: add pull request event types 2024-03-27 12:00:24 +09:00
0241fe5c13 fix: missing git binary on lambda dockerfile 2024-03-26 23:58:07 +00:00
d250cb46f4 fix: missing requirements.txt on lambda dockerfile 2024-03-26 22:28:19 +00:00
c97702982c fix image 2024-03-26 23:09:37 +02:00
2f823fb4e1 update deprecated plugin 2024-03-26 23:06:07 +02:00
736c8a6953 Refactor markdown image syntax and enhance documentation presentation 2024-03-26 23:00:57 +02:00
Tal
26c4a98fc8 Merge pull request #820 from riya-amemiya/riya-amemiya/change_gpt-4-turbo_model
add support for gpt-4-turbo-preview model
2024-03-26 10:46:51 +02:00
a7494746df revert default model 2024-03-26 16:21:30 +09:00
Tal
182e485741 Merge pull request #821 from Codium-ai/tr/installation_id
logs
2024-03-26 08:12:43 +02:00
1491bcba96 logs 2024-03-26 08:09:33 +02:00
d064a352ad feat(pr_agent): add support for gpt-4-turbo-preview model and update default settings 2024-03-26 14:47:05 +09:00
9c284e64cf dont log pr-agent bot 2024-03-25 12:27:45 +02:00
903d74b2f7 ignore_bot_pr = true 2024-03-25 11:42:24 +02:00
Tal
4651ced0f6 Merge pull request #817 from Codium-ai/tr/shorter_help
ignore bot
2024-03-25 09:17:07 +02:00
3cdadb3ad1 always ignore bot 2024-03-25 09:04:07 +02:00
Tal
cff6f2b597 Merge pull request #816 from Codium-ai/tr/shorter_help
Tr/shorter help
2024-03-25 08:55:33 +02:00
695f0706a8 Refactor help text for clarity and update configuration links in help.py; standardize variable naming in cli.py 2024-03-25 08:53:13 +02:00
07f5025b03 Refactor help text for clarity and update configuration links in help.py; standardize variable naming in cli.py 2024-03-25 08:51:59 +02:00
Tal
1701eb5b07 Merge pull request #815 from Codium-ai/tr/pypi
adjustments to pypi
2024-03-23 16:20:30 +02:00
ee4798acca adjustments to pypi 2024-03-23 16:16:32 +02:00
Tal
a355fb5d20 Merge pull request #814 from Codium-ai/tr/pypi
Tr/pypi
2024-03-23 11:20:04 +02:00
8e39394bcf adjustments to pypi 2024-03-23 11:16:21 +02:00
cfea8caf1c adjustments to pypi 2024-03-23 11:13:20 +02:00
9a46690121 adjustments to pypi 2024-03-23 09:55:08 +02:00
2fccadc469 adjustments to pypi 2024-03-22 21:43:41 +02:00
887d640ba5 Merge remote-tracking branch 'origin/main' into tr/pypi 2024-03-22 21:36:45 +02:00
0816370b1a adjustments to pypi 2024-03-22 21:36:22 +02:00
Tal
b4b2c7c620 Merge pull request #800 from koid/feature/ignore-bot-pr-on-github-app
Added `ignore_bot_pr` option
2024-03-21 18:42:45 +02:00
Tal
6323ff2ca2 Merge pull request #811 from veryyet/main
chore: fix some typos
2024-03-21 18:07:41 +02:00
92fbf21bd3 chore: fix some typos
Signed-off-by: veryyet <zhengxingru@outlook.com>
2024-03-21 14:41:29 +08:00
Tal
83ab5f7c1e Merge pull request #809 from Codium-ai/mrT23-patch-7
Update build-and-test.yaml
2024-03-21 08:21:21 +02:00
cae0b96054 use sender_type on bot check 2024-03-21 12:06:46 +09:00
4f2bbf936e Merge pull request #810 from Codium-ai/hl/docs_patch1
Small update to docs
2024-03-20 13:48:30 +02:00
61b2a1a053 update default 2024-03-20 11:11:06 +02:00
31bb72d65d add enable help text to documentation 2024-03-20 11:09:23 +02:00
Tal
a969d10381 Update build-and-test.yaml 2024-03-20 09:07:52 +02:00
29a2412de6 name 2024-03-20 08:36:46 +02:00
Tal
11502c5938 Merge pull request #807 from Codium-ai/tr/persistent_improve
Add persistent improve
2024-03-20 08:16:59 +02:00
b70225294c Update 'improve' tool documentation and functionality: Add persistent comment option, adjust default values, and enhance comment handling in pr_code_suggestions.py 2024-03-20 08:14:08 +02:00
Tal
f121652e4d Update improve.md 2024-03-19 17:29:21 +02:00
cf15f768fc Review vs. Improve tools comparison 2024-03-19 16:33:43 +02:00
Tal
795f619805 Merge pull request #806 from Codium-ai/tr/readme22
Review vs. Improve tools comparison
2024-03-19 16:19:04 +02:00
a39ff5d2dd Review vs. Improve tools comparison 2024-03-19 16:16:22 +02:00
Tal
158370e66c Update build-and-test.yaml 2024-03-19 14:36:16 +02:00
Tal
8ab27cf3b5 Merge pull request #805 from Codium-ai/hl/change_incremental_review_screenshot
Update review.md
2024-03-19 14:35:39 +02:00
7254211ed3 Update review.md 2024-03-19 13:38:54 +02:00
Tal
60fc6679c8 Merge pull request #804 from Codium-ai/mrT23-patch-7
Update build-and-test.yaml
2024-03-19 12:09:34 +02:00
Tal
2a76e77ba2 Update build-and-test.yaml 2024-03-19 12:02:38 +02:00
Tal
7ffdac98b3 Merge pull request #803 from Codium-ai/tr/readme22
Refactor improve.md: Improve image formatting, restructure content, a…
2024-03-19 10:00:51 +02:00
0aea45ec9c type 2024-03-19 10:00:04 +02:00
1db58fd028 Refactor improve.md: Improve image formatting, restructure content, and enhance descriptions 2024-03-19 09:56:10 +02:00
Tal
728997fd0e Merge pull request #802 from Codium-ai/tr/fixes4
Refactor review.md: Improve image formatting, restructure content, an…
2024-03-19 09:30:06 +02:00
Tal
be76a4132e Merge branch 'main' into tr/fixes4 2024-03-19 09:29:09 +02:00
ae09040543 Refactor review.md: Improve image formatting, restructure content, and enhance descriptions 2024-03-19 09:27:17 +02:00
Tal
431ed1babd Merge pull request #801 from Codium-ai/tr/fixes4
Update describe.md: Improve image formatting, restructure content, an…
2024-03-19 09:05:56 +02:00
edb59744ec Update describe.md: Improve image formatting, restructure content, and enhance descriptions 2024-03-19 09:03:50 +02:00
d9bf931a58 Update describe.md: Improve image formatting, restructure content, and enhance descriptions 2024-03-19 08:59:49 +02:00
b71523f13e use endswith 2024-03-18 16:14:58 +09:00
80a793a257 ignore bot pr option on github app mode 2024-03-18 16:14:54 +09:00
Tal
dd83b196b4 Merge pull request #781 from koid/feature/support-bedrock-claude3
added support for bedrock/claude3
2024-03-18 08:03:29 +02:00
Tal
eff6468651 Merge pull request #798 from Codium-ai/change-v-emoji
Replace checkmark emojis with tick emojis in documentation
2024-03-17 13:26:08 +02:00
Tal
b124dbffa6 Merge pull request #799 from Codium-ai/tr/split
Added docs for pr-agent-pro
2024-03-17 13:25:23 +02:00
008ee0dbc2 Replace checkmark emojis with tick emojis in documentation 2024-03-17 13:17:01 +02:00
1db03ccc36 Refactor PR-Agent Pro installation documentation and update navigation links 2024-03-17 13:15:21 +02:00
8ccb998b82 Refactor PR-Agent Pro installation documentation and update navigation links 2024-03-17 13:11:08 +02:00
Tal
8fea771502 Merge pull request #796 from Codium-ai/tr/split
Initialize current_labels to empty list if no labels exist in pr_revi…
2024-03-17 11:40:36 +02:00
b6dd57375f Initialize current_labels to empty list if no labels exist in pr_reviewer.py 2024-03-17 11:39:10 +02:00
Tal
11fed1e22d Merge pull request #756 from Codium-ai/tr/split
can PR be split feature
2024-03-17 01:03:06 -07:00
ac2c062190 readme 2024-03-17 10:01:30 +02:00
498b4cb34e readme 2024-03-17 09:59:55 +02:00
6d39773a17 prompt 2024-03-17 09:44:50 +02:00
99a676d792 Merge remote-tracking branch 'origin/main' into tr/split 2024-03-17 09:00:04 +02:00
Tal
1e504fc9c6 Merge pull request #795 from Codium-ai/tr/fixes4
Enhance AI handler logging and add main PR language attribute to AI h…
2024-03-16 04:53:24 -07:00
669e076938 Enhance AI handler logging and add main PR language attribute to AI handler in various tools 2024-03-16 13:52:02 +02:00
74345284bd Enhance AI handler logging and add main PR language attribute to AI handler in various tools 2024-03-16 13:47:44 +02:00
de0f3d3b0e Merge pull request #793 from Codium-ai/logo-and-title-sizing
add corect size logo to the header and adjust title spacing
2024-03-15 13:20:37 +02:00
44386573eb ad dcorect size logo to the header and adjust title spacing 2024-03-15 12:04:07 +01:00
Tal
e555610b82 Merge pull request #792 from Codium-ai/tr/fixes4
Refactor code in pr_code_suggestions.py
2024-03-15 03:47:34 -07:00
1593d8932b Refactor code in pr_code_suggestions.py and remove 'use_repo_settings_file' from azure.md and automations_and_usage.md 2024-03-15 12:37:50 +02:00
Tal
4425607a7e Merge pull request #786 from Codium-ai/add-google-analytics
Added Google Analytics to mkdocs configuration
2024-03-14 08:22:57 -07:00
b472149714 Replace hardcoded Google Analytics ID with environment variable in mkdocs.yml 2024-03-14 16:13:08 +02:00
50d0af0372 Added Google Analytics to mkdocs configuration 2024-03-14 13:56:10 +02:00
3bae515e39 add claude-3-haiku 2024-03-14 16:58:44 +09:00
0cdd3bf436 update docs 2024-03-13 14:23:57 +09:00
33d2d78bbc update docs 2024-03-13 11:36:13 +09:00
f94a0fd704 add Claude3Config 2024-03-13 11:24:51 +09:00
1ed2cd064a add config litellm.drop_params 2024-03-13 11:20:02 +09:00
d62796ac68 update max_tokens 2024-03-13 11:14:04 +09:00
3f66a1f0c9 update litellm 2024-03-13 11:10:19 +09:00
78cabf28a4 Update label comparison logic in pr_reviewer.py and pr_description.py to consider unordered lists 2024-03-12 18:25:42 +02:00
8b29c3a2be typo 2024-03-12 18:18:08 +02:00
Tal
53cc929d8a Merge pull request #780 from Codium-ai/tr/links
update links
2024-03-12 08:51:44 -07:00
785fbe04ae update links 2024-03-12 17:42:19 +02:00
Tal
d201403036 Merge pull request #779 from Codium-ai/tr/describe_keep_labels
Update get_pr_labels method to support label updates
2024-03-12 08:18:24 -07:00
Tal
b8a1378d1c Merge pull request #776 from Codium-ai/fix-docs-footer
Update footer title and improve responsive design in footer.html
2024-03-12 08:14:13 -07:00
31a8f5302a Update get_pr_labels method to support label updates and prevent unnecessary label republishing 2024-03-12 17:02:45 +02:00
5f98a0c539 Update footer title and improve responsive design in footer.html 2024-03-12 10:22:48 +02:00
8fb75c16af doc update 2024-03-11 20:08:16 +02:00
c876f271a4 contains several themes 2024-03-10 17:13:40 +02:00
4810b8549b docs 2024-03-10 16:59:37 +02:00
10a96d61ca Merge remote-tracking branch 'origin/main' into tr/split
# Conflicts:
#	pr_agent/settings/pr_reviewer_prompts.toml
2024-03-10 16:57:25 +02:00
8324e9a38d can_be_split 2024-03-10 16:56:32 +02:00
88 changed files with 2338 additions and 1295 deletions

View File

@ -2,8 +2,11 @@ name: Build-and-test
on: on:
push: push:
branches:
- main
pull_request: pull_request:
types: [ opened, reopened ] branches:
- main
jobs: jobs:
build-and-test: build-and-test:

View File

@ -29,4 +29,5 @@ jobs:
mkdocs-material- mkdocs-material-
- run: pip install mkdocs-material - run: pip install mkdocs-material
- run: pip install "mkdocs-material[imaging]" - run: pip install "mkdocs-material[imaging]"
- run: pip install mkdocs-glightbox
- run: mkdocs gh-deploy -f docs/mkdocs.yml --force - run: mkdocs gh-deploy -f docs/mkdocs.yml --force

View File

@ -1,7 +1,3 @@
[pr_reviewer] [pr_reviewer]
enable_review_labels_effort = true enable_review_labels_effort = true
enable_auto_approval = true enable_auto_approval = true
[pr_code_suggestions]
summarize=true

2
MANIFEST.in Normal file
View File

@ -0,0 +1,2 @@
recursive-include pr_agent *.toml
recursive-exclude pr_agent *.secrets.toml

186
README.md
View File

@ -6,13 +6,15 @@
<picture> <picture>
<source media="(prefers-color-scheme: dark)" srcset="https://codium.ai/images/pr_agent/logo-dark.png" width="330"> <source media="(prefers-color-scheme: dark)" srcset="https://codium.ai/images/pr_agent/logo-dark.png" width="330">
<source media="(prefers-color-scheme: light)" srcset="https://codium.ai/images/pr_agent/logo-light.png" width="330"> <source media="(prefers-color-scheme: light)" srcset="https://codium.ai/images/pr_agent/logo-light.png" width="330">
<img alt="logo"> <img src="https://codium.ai/images/pr_agent/logo-light.png" alt="logo" width="330">
</picture> </picture>
<br/> <br/>
Making pull requests less painful with an AI agent CodiumAI PR-Agent aims to help efficiently review and handle pull requests, by providing AI feedbacks and suggestions
</div> </div>
[![GitHub license](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://github.com/Codium-ai/pr-agent/blob/main/LICENSE) [![GitHub license](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://github.com/Codium-ai/pr-agent/blob/main/LICENSE)
[![Static Badge](https://img.shields.io/badge/Chrome-Extension-violet)](https://chromewebstore.google.com/detail/pr-agent-chrome-extension/ephlnjeghhogofkifjloamocljapahnl)
[![Discord](https://badgen.net/badge/icon/discord?icon=discord&label&color=purple)](https://discord.com/channels/1057273017547378788/1126104260430528613) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label&color=purple)](https://discord.com/channels/1057273017547378788/1126104260430528613)
[![Twitter](https://img.shields.io/twitter/follow/codiumai)](https://twitter.com/codiumai) [![Twitter](https://img.shields.io/twitter/follow/codiumai)](https://twitter.com/codiumai)
<a href="https://github.com/Codium-ai/pr-agent/commits/main"> <a href="https://github.com/Codium-ai/pr-agent/commits/main">
@ -20,83 +22,88 @@ Making pull requests less painful with an AI agent
</a> </a>
</div> </div>
### [Documentation](https://pr-agent-docs.codium.ai/)
- See the [Installation Guide](https://pr-agent-docs.codium.ai/installation/) for instructions on installing PR-Agent on different platforms.
- See the [Usage Guide](https://pr-agent-docs.codium.ai/usage-guide/) for instructions on running PR-Agent tools via different interfaces, such as CLI, PR Comments, or by automatically triggering them when a new PR is opened.
- See the [Tools Guide](https://pr-agent-docs.codium.ai/tools/) for a detailed description of the different tools, and the available configurations for each tool.
## Table of Contents ## Table of Contents
- [News and Updates](#news-and-updates) - [News and Updates](#news-and-updates)
- [Overview](#overview) - [Overview](#overview)
- [Example results](#example-results) - [Example results](#example-results)
- [Try it now](#try-it-now) - [Try it now](#try-it-now)
- [Installation](#installation)
- [PR-Agent Pro 💎](#pr-agent-pro-) - [PR-Agent Pro 💎](#pr-agent-pro-)
- [How it works](#how-it-works) - [How it works](#how-it-works)
- [Why use PR-Agent?](#why-use-pr-agent) - [Why use PR-Agent?](#why-use-pr-agent)
## News and Updates ## News and Updates
### Jan 10, 2024 ### May 19, 2024
- A new [knowledge-base website](https://pr-agent-docs.codium.ai/) for PR-Agent is now available. It includes detailed information about the different tools, usage guides and more, in an accessible and organized format. GPT-4o is now the default fast model ("Turbo"). This model will be used for all commands except `review` and `improve`, which will still use "GPT-4-2024-04-09", since they are harder and would still benefit from the larger model.
### Jan 8, 2024 ### May 12, 2024
Inspired by [AlphaCodium](https://github.com/Codium-ai/AlphaCodium) flow engineering scheme, PR-Agent now performs **self-reflection** on the code suggestions it provides,
enabling to remove invalid suggestions, and score the valid ones. The suggestions will be presented sorted by their score, enabling to focus on the most important ones first.
- A new tool, [Find Similar Code](https://pr-agent-docs.codium.ai/tools/similar_code/) 💎 is now available. You can also choose to automatically remove suggestions below a certain importance score threshold, by setting the `pr_code_suggestions.suggestions_score_threshold` [configuration](https://pr-agent-docs.codium.ai/tools/improve/#configuration-options).
<br>This tool retrieves the most similar code components from inside the organization's codebase, or from open-source code:
<kbd><a href="https://codium.ai/images/pr_agent/similar_code.mp4"><img src="https://codium.ai/images/pr_agent/similar_code_global2.png" width="512"></a></kbd> <kbd><img src="https://codium.ai/images/pr_agent/self_reflection1.png" width="512"></kbd>
(click on the image to see an instructional video) <kbd><img src="https://codium.ai/images/pr_agent/self_reflection2.png" width="512"></kbd>
### Feb 29, 2024
- You can now use the repo's [wiki page](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/) to set configurations for PR-Agent 💎
<kbd><img src="https://codium.ai/images/pr_agent/wiki_configuration.png" width="512"></kbd> ### May 2, 2024
Check out the new [PR-Agent Chrome Extension](https://chromewebstore.google.com/detail/pr-agent-chrome-extension/ephlnjeghhogofkifjloamocljapahnl) 🚀🚀🚀
This toolbar integrates seamlessly with your GitHub environment, allowing you to access PR-Agent tools [directly from the GitHub interface](https://www.youtube.com/watch?v=gT5tli7X4H4).
You can also easily export your chosen configuration, and use it for the automatic commands.
<kbd><img src="https://codium.ai/images/pr_agent/toolbar1.png" width="512"></kbd>
<kbd><img src="https://codium.ai/images/pr_agent/toolbar2.png" width="512"></kbd>
## Overview ## Overview
<div style="text-align:left;"> <div style="text-align:left;">
CodiumAI PR-Agent is an open-source tool to help efficiently review and handle pull requests.
- See the [Installation Guide](https://pr-agent-docs.codium.ai/installation/) for instructions on installing and running the tool on different git platforms.
- See the [Usage Guide](https://pr-agent-docs.codium.ai/usage-guide/) for instructions on running the PR-Agent commands via different interfaces, including _CLI_, _online usage_, or by _automatically triggering_ them when a new PR is opened.
- See the [Tools Guide](https://pr-agent-docs.codium.ai/tools/) for a detailed description of the different tools.
Supported commands per platform: Supported commands per platform:
| | | GitHub | Gitlab | Bitbucket | Azure DevOps | | | | GitHub | Gitlab | Bitbucket | Azure DevOps |
|-------|-------------------------------------------------------------------------------------------------------------------|:--------------------:|:--------------------:|:--------------------:|:--------------------:| |-------|---------------------------------------------------------------------------------------------------------|:--------------------:|:--------------------:|:--------------------:|:--------------------:|
| TOOLS | Review | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | TOOLS | Review | ✅ | ✅ | ✅ | ✅ |
| | ⮑ Incremental | :white_check_mark: | | | | | | ⮑ Incremental | ✅ | | | |
| | ⮑ [SOC2 Compliance](https://pr-agent-docs.codium.ai/tools/review/#soc2-ticket-compliance) 💎 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | ⮑ [SOC2 Compliance](https://pr-agent-docs.codium.ai/tools/review/#soc2-ticket-compliance) 💎 | ✅ | ✅ | ✅ | ✅ |
| | Describe | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | Describe | ✅ | ✅ | ✅ | ✅ |
| | ⮑ [Inline File Summary](https://pr-agent-docs.codium.ai/tools/describe#inline-file-summary) 💎 | :white_check_mark: | | | | | | ⮑ [Inline File Summary](https://pr-agent-docs.codium.ai/tools/describe#inline-file-summary) 💎 | | | | |
| | Improve | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | Improve | ✅ | ✅ | ✅ | ✅ |
| | ⮑ Extended | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | ⮑ Extended | ✅ | ✅ | ✅ | ✅ |
| | Ask | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | Ask | ✅ | ✅ | ✅ | ✅ |
| | ⮑ [Ask on code lines](https://pr-agent-docs.codium.ai/tools/ask#ask-lines) | :white_check_mark: | :white_check_mark: | | | | | ⮑ [Ask on code lines](https://pr-agent-docs.codium.ai/tools/ask#ask-lines) | ✅ | ✅ | | |
| | [Custom Suggestions](https://pr-agent-docs.codium.ai/tools/custom_suggestions/) 💎 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | [Custom Prompt](https://pr-agent-docs.codium.ai/tools/custom_prompt/) 💎 | ✅ | ✅ | ✅ | ✅ |
| | [Test](https://pr-agent-docs.codium.ai/tools/test/) 💎 | :white_check_mark: | :white_check_mark: | | :white_check_mark: | | | [Test](https://pr-agent-docs.codium.ai/tools/test/) 💎 | ✅ | ✅ | | |
| | Reflect and Review | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | Reflect and Review | ✅ | ✅ | ✅ | ✅ |
| | Update CHANGELOG.md | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | Update CHANGELOG.md | ✅ | ✅ | ✅ | ✅ |
| | Find Similar Issue | :white_check_mark: | | | | | | Find Similar Issue | ✅ | | | |
| | [Add PR Documentation](https://pr-agent-docs.codium.ai/tools/documentation/) 💎 | :white_check_mark: | :white_check_mark: | | :white_check_mark: | | | [Add PR Documentation](https://pr-agent-docs.codium.ai/tools/documentation/) 💎 | ✅ | ✅ | | |
| | [Custom Labels](https://pr-agent-docs.codium.ai/tools/custom_labels/) 💎 | :white_check_mark: | :white_check_mark: | | :white_check_mark: | | | [Custom Labels](https://pr-agent-docs.codium.ai/tools/custom_labels/) 💎 | ✅ | ✅ | | |
| | [Analyze](https://pr-agent-docs.codium.ai/tools/analyze/) 💎 | :white_check_mark: | :white_check_mark: | | :white_check_mark: | | | [Analyze](https://pr-agent-docs.codium.ai/tools/analyze/) 💎 | ✅ | ✅ | | |
| | [CI Feedback](https://pr-agent-docs.codium.ai/tools/ci_feedback/) 💎 | :white_check_mark: | | | | | | [CI Feedback](https://pr-agent-docs.codium.ai/tools/ci_feedback/) 💎 | | | | |
| | [Similar Code](https://pr-agent-docs.codium.ai/tools/similar_code/) 💎 | :white_check_mark: | | | | | | [Similar Code](https://pr-agent-docs.codium.ai/tools/similar_code/) 💎 | | | | |
| | | | | | | | | | | | | |
| USAGE | CLI | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | USAGE | CLI | ✅ | ✅ | ✅ | ✅ |
| | App / webhook | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | App / webhook | ✅ | ✅ | ✅ | ✅ |
| | Tagging bot | :white_check_mark: | | | | | | Tagging bot | ✅ | | | |
| | Actions | :white_check_mark: | | :white_check_mark: | | | | Actions | ✅ | | | |
| | | | | | | | | | | | | |
| CORE | PR compression | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | CORE | PR compression | ✅ | ✅ | ✅ | ✅ |
| | Repo language prioritization | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | Repo language prioritization | ✅ | ✅ | ✅ | ✅ |
| | Adaptive and token-aware file patch fitting | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | Adaptive and token-aware file patch fitting | ✅ | ✅ | ✅ | ✅ |
| | Multiple models support | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | Multiple models support | ✅ | ✅ | ✅ | ✅ |
| | [Static code analysis](https://pr-agent-docs.codium.ai/core-abilities/#static-code-analysis) 💎 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | [Static code analysis](https://pr-agent-docs.codium.ai/core-abilities/#static-code-analysis) 💎 | ✅ | ✅ | ✅ | ✅ |
| | [Global and wiki configurations](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/) 💎 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | [Global and wiki configurations](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/) 💎 | ✅ | ✅ | ✅ | ✅ |
| | [PR interactive actions](https://www.codium.ai/images/pr_agent/pr-actions.mp4) 💎 | :white_check_mark: | | | | | | [PR interactive actions](https://www.codium.ai/images/pr_agent/pr-actions.mp4) 💎 | ✅ | | | |
- 💎 means this feature is available only in [PR-Agent Pro](https://www.codium.ai/pricing/) - 💎 means this feature is available only in [PR-Agent Pro](https://www.codium.ai/pricing/)
[//]: # (- Support for additional git providers is described in [here]&#40;./docs/Full_environments.md&#41;) [//]: # (- Support for additional git providers is described in [here]&#40;./docs/Full_environments.md&#41;)
@ -120,13 +127,13 @@ ___
\ \
**Analyze 💎 ([`/analyze`](https://pr-agent-docs.codium.ai/tools/analyze/))**: Identify code components that changed in the PR, and enables to interactively generate tests, docs, and code suggestions for each component. **Analyze 💎 ([`/analyze`](https://pr-agent-docs.codium.ai/tools/analyze/))**: Identify code components that changed in the PR, and enables to interactively generate tests, docs, and code suggestions for each component.
\ \
**Custom Suggestions 💎 ([`/custom_suggestions`](https://pr-agent-docs.codium.ai/tools/custom_suggestions/))**: Automatically generates custom suggestions for improving the PR code, based on specific guidelines defined by the user. **Custom Prompt 💎 ([`/custom_prompt`](https://pr-agent-docs.codium.ai/tools/custom_prompt/))**: Automatically generates custom suggestions for improving the PR code, based on specific guidelines defined by the user.
\ \
**Generate Tests 💎 ([`/test component_name`](https://pr-agent-docs.codium.ai/tools/test/))**: Generates unit tests for a selected component, based on the PR code changes. **Generate Tests 💎 ([`/test component_name`](https://pr-agent-docs.codium.ai/tools/test/))**: Generates unit tests for a selected component, based on the PR code changes.
\ \
**CI Feedback 💎 ([`/checks ci_job`](https://pr-agent-docs.codium.ai/tools/ci_feedback/))**: Automatically generates feedback and analysis for a failed CI job. **CI Feedback 💎 ([`/checks ci_job`](https://pr-agent-docs.codium.ai/tools/ci_feedback/))**: Automatically generates feedback and analysis for a failed CI job.
\ \
**Similar Code 💎 ([`/find_similar_component`](https://pr-agent-docs.codium.ai/tools/similar_code//))**: Retrieves the most similar code components from inside the organization's codebase, or from open-source code. **Similar Code 💎 ([`/find_similar_component`](https://pr-agent-docs.codium.ai/tools/similar_code/))**: Retrieves the most similar code components from inside the organization's codebase, or from open-source code.
___ ___
## Example results ## Example results
@ -225,31 +232,47 @@ Note that when you set your own PR-Agent or use CodiumAI hosted PR-Agent, there
--- ---
## Installation [//]: # (## Installation)
To use your own version of PR-Agent, you first need to acquire two tokens:
1. An OpenAI key from [here](https://platform.openai.com/), with access to GPT-4. [//]: # (To use your own version of PR-Agent, you first need to acquire two tokens:)
2. A GitHub personal access token (classic) with the repo scope.
There are several ways to use PR-Agent: [//]: # ()
[//]: # (1. An OpenAI key from [here]&#40;https://platform.openai.com/&#41;, with access to GPT-4.)
**Locally** [//]: # (2. A GitHub personal access token &#40;classic&#41; with the repo scope.)
- [Use Docker image (no installation required)](https://pr-agent-docs.codium.ai/installation/locally/#use-docker-image-no-installation-required)
- [Run from source](https://pr-agent-docs.codium.ai/installation/locally/#run-from-source)
**GitHub specific methods** [//]: # ()
- [Run as a GitHub Action](https://pr-agent-docs.codium.ai/installation/github/#run-as-a-github-action) [//]: # (There are several ways to use PR-Agent:)
- [Run as a GitHub App](https://pr-agent-docs.codium.ai/installation/github/#run-as-a-github-app)
**GitLab specific methods** [//]: # ()
- [Run a GitLab webhook server](https://pr-agent-docs.codium.ai/installation/gitlab/) [//]: # (**Locally**)
**BitBucket specific methods** [//]: # (- [Using pip package]&#40;https://pr-agent-docs.codium.ai/installation/locally/#using-pip-package&#41;)
- [Run as a Bitbucket Pipeline](https://pr-agent-docs.codium.ai/installation/bitbucket/)
[//]: # (- [Using Docker image]&#40;https://pr-agent-docs.codium.ai/installation/locally/#using-docker-image&#41;)
[//]: # (- [Run from source]&#40;https://pr-agent-docs.codium.ai/installation/locally/#run-from-source&#41;)
[//]: # ()
[//]: # (**GitHub specific methods**)
[//]: # (- [Run as a GitHub Action]&#40;https://pr-agent-docs.codium.ai/installation/github/#run-as-a-github-action&#41;)
[//]: # (- [Run as a GitHub App]&#40;https://pr-agent-docs.codium.ai/installation/github/#run-as-a-github-app&#41;)
[//]: # ()
[//]: # (**GitLab specific methods**)
[//]: # (- [Run a GitLab webhook server]&#40;https://pr-agent-docs.codium.ai/installation/gitlab/&#41;)
[//]: # ()
[//]: # (**BitBucket specific methods**)
[//]: # (- [Run as a Bitbucket Pipeline]&#40;https://pr-agent-docs.codium.ai/installation/bitbucket/&#41;)
## PR-Agent Pro 💎 ## PR-Agent Pro 💎
[PR-Agent Pro](https://www.codium.ai/pricing/) is a hosted version of PR-Agent, provided by CodiumAI. It is available for a monthly fee, and provides the following benefits: [PR-Agent Pro](https://www.codium.ai/pricing/) is a hosted version of PR-Agent, provided by CodiumAI. It is available for a monthly fee, and provides the following benefits:
1. **Fully managed** - We take care of everything for you - hosting, models, regular updates, and more. Installation is as simple as signing up and adding the PR-Agent app to your GitHub\BitBucket repo. 1. **Fully managed** - We take care of everything for you - hosting, models, regular updates, and more. Installation is as simple as signing up and adding the PR-Agent app to your GitHub\GitLab\BitBucket repo.
2. **Improved privacy** - No data will be stored or used to train models. PR-Agent Pro will employ zero data retention, and will use an OpenAI account with zero data retention. 2. **Improved privacy** - No data will be stored or used to train models. PR-Agent Pro will employ zero data retention, and will use an OpenAI account with zero data retention.
3. **Improved support** - PR-Agent Pro users will receive priority support, and will be able to request new features and capabilities. 3. **Improved support** - PR-Agent Pro users will receive priority support, and will be able to request new features and capabilities.
4. **Extra features** -In addition to the benefits listed above, PR-Agent Pro will emphasize more customization, and the usage of static code analysis, in addition to LLM logic, to improve results. 4. **Extra features** -In addition to the benefits listed above, PR-Agent Pro will emphasize more customization, and the usage of static code analysis, in addition to LLM logic, to improve results.
@ -279,11 +302,22 @@ Here are some advantages of PR-Agent:
## Data privacy ## Data privacy
If you host PR-Agent with your OpenAI API key, it is between you and OpenAI. You can read their API data privacy policy here: ### Self-hosted PR-Agent
- If you host PR-Agent with your OpenAI API key, it is between you and OpenAI. You can read their API data privacy policy here:
https://openai.com/enterprise-privacy https://openai.com/enterprise-privacy
When using PR-Agent Pro 💎, hosted by CodiumAI, we will not store any of your data, nor will we use it for training. ### CodiumAI-hosted PR-Agent Pro 💎
You will also benefit from an OpenAI account with zero data retention.
- When using PR-Agent Pro 💎, hosted by CodiumAI, we will not store any of your data, nor will we use it for training. You will also benefit from an OpenAI account with zero data retention.
- For certain clients, CodiumAI-hosted PR-Agent Pro will use CodiumAIs proprietary models — if this is the case, you will be notified.
- No passive collection of Code and Pull Requests data — PR-Agent will be active only when you invoke it, and it will then extract and analyze only data relevant to the executed command and queried pull request.
### PR-Agent Chrome extension
- The [PR-Agent Chrome extension](https://chromewebstore.google.com/detail/pr-agent-chrome-extension/ephlnjeghhogofkifjloamocljapahnl) serves solely to modify the visual appearance of a GitHub PR screen. It does not transmit any user's repo or pull request code. Code is only sent for processing when a user submits a GitHub comment that activates a PR-Agent tool, in accordance with the standard privacy policy of PR-Agent.
## Links ## Links

View File

@ -1,10 +1,10 @@
FROM public.ecr.aws/lambda/python:3.10 FROM public.ecr.aws/lambda/python:3.10
RUN yum update -y && \ RUN yum update -y && \
yum install -y gcc python3-devel && \ yum install -y gcc python3-devel git && \
yum clean all yum clean all
ADD pyproject.toml . ADD pyproject.toml requirements.txt .
RUN pip install . && rm pyproject.toml RUN pip install . && rm pyproject.toml
RUN pip install mangum==0.17.0 RUN pip install mangum==0.17.0
COPY pr_agent/ ${LAMBDA_TASK_ROOT}/pr_agent/ COPY pr_agent/ ${LAMBDA_TASK_ROOT}/pr_agent/

View File

@ -1,15 +1 @@
# To install: # [Visit Our Docs Portal](https://pr-agent-docs.codium.ai/)
pip install mkdocs
pip install mkdocs-material
pip install mkdocs-material-extensions
pip install "mkdocs-material[imaging]"
# docs
To run localy: `mkdocs serve`
To expand and customize the theme: [Material MKDocs](https://squidfunk.github.io/mkdocs-material/)
The deployment is managed on the gh-pages branches.
After each merge to main the deplloyment will be taken care of by GH action automatically and the new version will be available at: [Docs](https://codium-ai.github.io/docs/)
Github action is located in `.github/workflows/ci.yml` file.

140
docs/docs/assets/logo.svg Normal file
View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 28.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
<g>
<defs>
<rect id="SVGID_1_" x="0.4" y="0.1" width="63.4" height="63.4"/>
</defs>
<clipPath id="SVGID_00000008836131916906499950000015813697852011234749_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_00000008836131916906499950000015813697852011234749_)">
<path fill="#05E5AD" d="M21.4,9.8c3,0,5.9,0.7,8.5,1.9c-5.7,3.4-9.8,11.1-9.8,20.1c0,9,4,16.7,9.8,20.1c-2.6,1.2-5.5,1.9-8.5,1.9
c-11.6,0-21-9.8-21-22S9.8,9.8,21.4,9.8z"/>
<radialGradient id="SVGID_00000150822754378345238340000008985053211526864828_" cx="-140.0905" cy="350.1757" r="4.8781" gradientTransform="matrix(-4.7708 -6.961580e-02 -0.1061 7.2704 -601.3099 -2523.8489)" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#6447FF"/>
<stop offset="6.666670e-02" style="stop-color:#6348FE"/>
<stop offset="0.1333" style="stop-color:#614DFC"/>
<stop offset="0.2" style="stop-color:#5C54F8"/>
<stop offset="0.2667" style="stop-color:#565EF3"/>
<stop offset="0.3333" style="stop-color:#4E6CEC"/>
<stop offset="0.4" style="stop-color:#447BE4"/>
<stop offset="0.4667" style="stop-color:#3A8DDB"/>
<stop offset="0.5333" style="stop-color:#2F9FD1"/>
<stop offset="0.6" style="stop-color:#25B1C8"/>
<stop offset="0.6667" style="stop-color:#1BC0C0"/>
<stop offset="0.7333" style="stop-color:#13CEB9"/>
<stop offset="0.8" style="stop-color:#0DD8B4"/>
<stop offset="0.8667" style="stop-color:#08DFB0"/>
<stop offset="0.9333" style="stop-color:#06E4AE"/>
<stop offset="1" style="stop-color:#05E5AD"/>
</radialGradient>
<path fill="url(#SVGID_00000150822754378345238340000008985053211526864828_)" d="M21.4,9.8c3,0,5.9,0.7,8.5,1.9
c-5.7,3.4-9.8,11.1-9.8,20.1c0,9,4,16.7,9.8,20.1c-2.6,1.2-5.5,1.9-8.5,1.9c-11.6,0-21-9.8-21-22S9.8,9.8,21.4,9.8z"/>
<radialGradient id="SVGID_00000022560571240417802950000012439139323268113305_" cx="-191.7649" cy="385.7387" r="4.8781" gradientTransform="matrix(-2.5514 -0.7616 -0.8125 2.7217 -130.733 -1180.2209)" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#6447FF"/>
<stop offset="6.666670e-02" style="stop-color:#6348FE"/>
<stop offset="0.1333" style="stop-color:#614DFC"/>
<stop offset="0.2" style="stop-color:#5C54F8"/>
<stop offset="0.2667" style="stop-color:#565EF3"/>
<stop offset="0.3333" style="stop-color:#4E6CEC"/>
<stop offset="0.4" style="stop-color:#447BE4"/>
<stop offset="0.4667" style="stop-color:#3A8DDB"/>
<stop offset="0.5333" style="stop-color:#2F9FD1"/>
<stop offset="0.6" style="stop-color:#25B1C8"/>
<stop offset="0.6667" style="stop-color:#1BC0C0"/>
<stop offset="0.7333" style="stop-color:#13CEB9"/>
<stop offset="0.8" style="stop-color:#0DD8B4"/>
<stop offset="0.8667" style="stop-color:#08DFB0"/>
<stop offset="0.9333" style="stop-color:#06E4AE"/>
<stop offset="1" style="stop-color:#05E5AD"/>
</radialGradient>
<path fill="url(#SVGID_00000022560571240417802950000012439139323268113305_)" d="M38,18.3c-2.1-2.8-4.9-5.1-8.1-6.6
c2-1.2,4.2-1.9,6.6-1.9c2.2,0,4.3,0.6,6.2,1.7C40.8,12.9,39.2,15.3,38,18.3L38,18.3z"/>
<radialGradient id="SVGID_00000143611122169386473660000017673587931016751800_" cx="-194.7918" cy="395.2442" r="4.8781" gradientTransform="matrix(-2.5514 -0.7616 -0.8125 2.7217 -130.733 -1172.9556)" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#6447FF"/>
<stop offset="6.666670e-02" style="stop-color:#6348FE"/>
<stop offset="0.1333" style="stop-color:#614DFC"/>
<stop offset="0.2" style="stop-color:#5C54F8"/>
<stop offset="0.2667" style="stop-color:#565EF3"/>
<stop offset="0.3333" style="stop-color:#4E6CEC"/>
<stop offset="0.4" style="stop-color:#447BE4"/>
<stop offset="0.4667" style="stop-color:#3A8DDB"/>
<stop offset="0.5333" style="stop-color:#2F9FD1"/>
<stop offset="0.6" style="stop-color:#25B1C8"/>
<stop offset="0.6667" style="stop-color:#1BC0C0"/>
<stop offset="0.7333" style="stop-color:#13CEB9"/>
<stop offset="0.8" style="stop-color:#0DD8B4"/>
<stop offset="0.8667" style="stop-color:#08DFB0"/>
<stop offset="0.9333" style="stop-color:#06E4AE"/>
<stop offset="1" style="stop-color:#05E5AD"/>
</radialGradient>
<path fill="url(#SVGID_00000143611122169386473660000017673587931016751800_)" d="M38,45.2c1.2,3,2.9,5.3,4.7,6.8
c-1.9,1.1-4,1.7-6.2,1.7c-2.3,0-4.6-0.7-6.6-1.9C33.1,50.4,35.8,48.1,38,45.2L38,45.2z"/>
<path fill="#684BFE" d="M20.1,31.8c0-9,4-16.7,9.8-20.1c3.2,1.5,6,3.8,8.1,6.6c-1.5,3.7-2.5,8.4-2.5,13.5s0.9,9.8,2.5,13.5
c-2.1,2.8-4.9,5.1-8.1,6.6C24.1,48.4,20.1,40.7,20.1,31.8z"/>
<radialGradient id="SVGID_00000147942998054305738810000004710078864578628519_" cx="-212.7358" cy="363.2475" r="4.8781" gradientTransform="matrix(-2.3342 -1.063 -1.623 3.5638 149.3813 -1470.1027)" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#6447FF"/>
<stop offset="6.666670e-02" style="stop-color:#6348FE"/>
<stop offset="0.1333" style="stop-color:#614DFC"/>
<stop offset="0.2" style="stop-color:#5C54F8"/>
<stop offset="0.2667" style="stop-color:#565EF3"/>
<stop offset="0.3333" style="stop-color:#4E6CEC"/>
<stop offset="0.4" style="stop-color:#447BE4"/>
<stop offset="0.4667" style="stop-color:#3A8DDB"/>
<stop offset="0.5333" style="stop-color:#2F9FD1"/>
<stop offset="0.6" style="stop-color:#25B1C8"/>
<stop offset="0.6667" style="stop-color:#1BC0C0"/>
<stop offset="0.7333" style="stop-color:#13CEB9"/>
<stop offset="0.8" style="stop-color:#0DD8B4"/>
<stop offset="0.8667" style="stop-color:#08DFB0"/>
<stop offset="0.9333" style="stop-color:#06E4AE"/>
<stop offset="1" style="stop-color:#05E5AD"/>
</radialGradient>
<path fill="url(#SVGID_00000147942998054305738810000004710078864578628519_)" d="M50.7,42.5c0.6,3.3,1.5,6.1,2.5,8
c-1.8,2-3.8,3.1-6,3.1c-1.6,0-3.1-0.6-4.5-1.7C46.1,50.2,48.9,46.8,50.7,42.5L50.7,42.5z"/>
<radialGradient id="SVGID_00000083770737908230256670000016126156495859285174_" cx="-208.5327" cy="357.2025" r="4.8781" gradientTransform="matrix(-2.3342 -1.063 -1.623 3.5638 149.3813 -1476.8097)" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#6447FF"/>
<stop offset="6.666670e-02" style="stop-color:#6348FE"/>
<stop offset="0.1333" style="stop-color:#614DFC"/>
<stop offset="0.2" style="stop-color:#5C54F8"/>
<stop offset="0.2667" style="stop-color:#565EF3"/>
<stop offset="0.3333" style="stop-color:#4E6CEC"/>
<stop offset="0.4" style="stop-color:#447BE4"/>
<stop offset="0.4667" style="stop-color:#3A8DDB"/>
<stop offset="0.5333" style="stop-color:#2F9FD1"/>
<stop offset="0.6" style="stop-color:#25B1C8"/>
<stop offset="0.6667" style="stop-color:#1BC0C0"/>
<stop offset="0.7333" style="stop-color:#13CEB9"/>
<stop offset="0.8" style="stop-color:#0DD8B4"/>
<stop offset="0.8667" style="stop-color:#08DFB0"/>
<stop offset="0.9333" style="stop-color:#06E4AE"/>
<stop offset="1" style="stop-color:#05E5AD"/>
</radialGradient>
<path fill="url(#SVGID_00000083770737908230256670000016126156495859285174_)" d="M42.7,11.5c1.4-1.1,2.9-1.7,4.5-1.7
c2.2,0,4.3,1.1,6,3.1c-1,2-1.9,4.7-2.5,8C48.9,16.7,46.1,13.4,42.7,11.5L42.7,11.5z"/>
<path fill="#684BFE" d="M38,45.2c2.8-3.7,4.4-8.4,4.4-13.5c0-5.1-1.7-9.8-4.4-13.5c1.2-3,2.9-5.3,4.7-6.8c3.4,1.9,6.2,5.3,8,9.5
c-0.6,3.2-0.9,6.9-0.9,10.8s0.3,7.6,0.9,10.8c-1.8,4.3-4.6,7.6-8,9.5C40.8,50.6,39.2,48.2,38,45.2L38,45.2z"/>
<path fill="#321BB2" d="M38,45.2c-1.5-3.7-2.5-8.4-2.5-13.5S36.4,22,38,18.3c2.8,3.7,4.4,8.4,4.4,13.5S40.8,41.5,38,45.2z"/>
<path fill="#05E6AD" d="M53.2,12.9c1.1-2,2.3-3.1,3.6-3.1c3.9,0,7,9.8,7,22s-3.1,22-7,22c-1.3,0-2.6-1.1-3.6-3.1
c3.4-3.8,5.7-10.8,5.7-18.8C58.8,23.8,56.6,16.8,53.2,12.9z"/>
<radialGradient id="SVGID_00000009565123575973598080000009335550354766300606_" cx="-7.8671" cy="278.2442" r="4.8781" gradientTransform="matrix(1.5187 0 0 -7.8271 69.237 2209.3281)" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#05E5AD"/>
<stop offset="0.32" style="stop-color:#05E5AD;stop-opacity:0"/>
<stop offset="0.9028" style="stop-color:#6447FF"/>
</radialGradient>
<path fill="url(#SVGID_00000009565123575973598080000009335550354766300606_)" d="M53.2,12.9c1.1-2,2.3-3.1,3.6-3.1
c3.9,0,7,9.8,7,22s-3.1,22-7,22c-1.3,0-2.6-1.1-3.6-3.1c3.4-3.8,5.7-10.8,5.7-18.8C58.8,23.8,56.6,16.8,53.2,12.9z"/>
<path fill="#684BFE" d="M52.8,31.8c0-3.9-0.8-7.6-2.1-10.8c0.6-3.3,1.5-6.1,2.5-8c3.4,3.8,5.7,10.8,5.7,18.8c0,8-2.3,15-5.7,18.8
c-1-2-1.9-4.7-2.5-8C52,39.3,52.8,35.7,52.8,31.8z"/>
<path fill="#321BB2" d="M50.7,42.5c-0.6-3.2-0.9-6.9-0.9-10.8s0.3-7.6,0.9-10.8c1.3,3.2,2.1,6.9,2.1,10.8S52,39.3,50.7,42.5z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -0,0 +1,28 @@
## PR-Agent chrome extension
- PR-Agent Chrome extension is a toolbar that integrates seamlessly with your GitHub environment, allowing you to access PR-Agent tools directly from the GitHub interface.
- With PR-Agent Chrome extension, it's [easier than ever](https://www.youtube.com/watch?v=gT5tli7X4H4) to interactively experiment with the different tools and configuration options.
- After you found the setup that works for you, you can also easily export it as a persistent configuration file, and use it for the automatic commands.
<kbd><img src="https://codium.ai/images/pr_agent/toolbar1.png" width="512"></kbd>
<kbd><img src="https://codium.ai/images/pr_agent/toolbar2.png" width="512"></kbd>
## Installation
Go to the marketplace and install the extension:
[PR-Agent Chrome Extension](https://chromewebstore.google.com/detail/pr-agent-chrome-extension/ephlnjeghhogofkifjloamocljapahnl)
## Pre-requisites
The PR-Agent Chrome extension will work on any repo where you have previously [installed PR-Agent](https://pr-agent-docs.codium.ai/installation/) (both for free and pro users).
## Data privacy and security
The PR-Agent Chrome extension only modifies the visual appearance of a GitHub PR screen. It does not transmit any user's repo or pull request code. Code is only sent for processing when a user submits a GitHub comment that activates a PR-Agent tool, in accordance with the standard [privacy policy of PR-Agent](https://pr-agent-docs.codium.ai/#pr-agent-chrome-extension).
## Roadmap
Stay tuned ...
<kbd><img src="https://codium.ai/images/pr_agent/chrome_extension_roadmap.png" width="512"></kbd>

View File

@ -43,7 +43,7 @@ We use [tiktoken](https://github.com/openai/tiktoken) to tokenize the patches af
#### Example #### Example
<kbd><img src=https://codium.ai/images/git_patch_logic.png width="768"></kbd> ![Core Abilities](https://codium.ai/images/git_patch_logic.png){width=768}
## YAML Prompting ## YAML Prompting
TBD TBD

View File

@ -5,94 +5,23 @@
--md-accent-fg-color: #AEA1F1; --md-accent-fg-color: #AEA1F1;
} }
.md-nav__title, .md-nav__link { .md-nav__title, .md-nav__link {
font-size: 16px; /* Adjust the font size as needed */ font-size: 16px;
} }
.md-tabs__link { .md-tabs__link {
font-size: 16px; /* Adjust the font size as needed */ font-size: 16px;
} }
.md-header__title { .md-header__title {
font-size: 20px; /* Adjust the font size as needed */ font-size: 20px;
margin-left: 0px !important;
} }
/* .md-content img {
@media (prefers-color-scheme: light) { border-width: 1px;
body { border-style: solid;
--md-primary-fg-color: #00ffee !important; border-color: black;
--md-primary-bg-color: #ff0000 !important; outline-width: 1px;
} outline-style: solid;
outline-color: darkgray;
body, .md-main, .md-content { }
background-color: #4312f5 !important;
}
}
@media (prefers-color-scheme: dark) {
body {
--md-primary-fg-color: #171518 !important;
--md-primary-bg-color: #171518 !important;
}
body, .md-main, .md-content {
background-color: #171518 !important;
}
.md-header__title {
color: #ffffff !important;
}
.md-tabs .md-tabs__link {
color: #ffffff !important;
}
.md-tabs .md-tabs__link:hover,
.md-tabs .md-tabs__link:focus {
color: #ffffff !important;
}
.md-header__button {
color: #ffffff !important;
}
.md-header__button svg {
fill: currentColor !important;
}
.md-header__button:hover,
.md-header__button:focus {
color: #ffffff !important;
}
.md-header__button:hover svg,
.md-header__button:focus svg {
fill: currentColor !important;
}
.md-search__icon svg {
fill: #ffffff !important;
}
.md-search__input {
color: #ffffff !important;
}
.md-nav__item--active > .md-nav__link--active,
.md-nav__link--active {
color: #AEA1F1 !important;
}
.md-nav--secondary .md-nav__title {
background: #171518;
box-shadow: 0 0 0.4rem 0.4rem #171518;
}
.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link {
background: #171518;
box-shadow: 0 0 0.4rem 0.4rem #171518;
}
.md-content a {
color: #AEA1F1 !important;
}
} */

View File

@ -12,120 +12,67 @@ CodiumAI PR-Agent is an open-source tool to help efficiently review and handle p
## PR-Agent Features ## PR-Agent Features
PR-Agent offers extensive pull request functionalities across various git providers. PR-Agent offers extensive pull request functionalities across various git providers.
| | | GitHub | Gitlab | Bitbucket | Azure DevOps | | | | GitHub | Gitlab | Bitbucket | Azure DevOps |
|-------|---------------------------------------------------------------------------------------------------------------------|:------:|:------:|:---------:|:------------:| |-------|-----------------------------------------------------------------------------------------------------------------------|:------:|:------:|:---------:|:------------:|
| TOOLS | Review | ✔️ | ✔️ | ✔️ | ✔️ | | TOOLS | Review | | | | |
| | ⮑ Incremental | ✔️ | | | | | | ⮑ Incremental | | | | |
| | ⮑ [SOC2 Compliance](https://pr-agent-docs.codium.ai/tools/review/#soc2-ticket-compliance){:target="_blank"} 💎 | ✔️ | ✔️ | ✔️ | ✔️ | | | ⮑ [SOC2 Compliance](https://pr-agent-docs.codium.ai/tools/review/#soc2-ticket-compliance){:target="_blank"} 💎 | | | | |
| | Ask | ✔️ | ✔️ | ✔️ | ✔️ | | | Ask | | | | |
| | Describe | ✔️ | ✔️ | ✔️ | ✔️ | | | Describe | | | | |
| | ⮑ [Inline file summary](https://pr-agent-docs.codium.ai/tools/describe/#inline-file-summary){:target="_blank"} 💎 | ✔️ | ✔️ | ✔️ | ✔️ | | | ⮑ [Inline file summary](https://pr-agent-docs.codium.ai/tools/describe/#inline-file-summary){:target="_blank"} 💎 | | | | |
| | Improve | ✔️ | ✔️ | ✔️ | ✔️ | | | Improve | | | | |
| | ⮑ Extended | ✔️ | ✔️ | ✔️ | ✔️ | | | ⮑ Extended | | | | |
| | [Custom Suggestions](./tools/custom_suggestions.md){:target="_blank"} 💎 | ✔️ | ✔️ | ✔️ | ✔️ | | | [Custom Prompt](./tools/custom_prompt.md){:target="_blank"} 💎 | | | | |
| | Reflect and Review | ✔️ | ✔️ | ✔️ | ✔️ | | | Reflect and Review | | | | |
| | Update CHANGELOG.md | ✔️ | ✔️ | ✔️ | | | | Update CHANGELOG.md | | | | |
| | Find Similar Issue | ✔️ | | | | | | Find Similar Issue | | | | |
| | [Add PR Documentation](./tools/documentation.md){:target="_blank"} 💎 | ✔️ | ✔️ | ✔️ | ✔️ | | | [Add PR Documentation](./tools/documentation.md){:target="_blank"} 💎 | | | | |
| | [Generate Custom Labels](./tools/describe.md#handle-custom-labels-from-the-repos-labels-page-💎){:target="_blank"} 💎 | ✔️ | ✔️ | | ✔️ | | | [Generate Custom Labels](./tools/describe.md#handle-custom-labels-from-the-repos-labels-page-💎){:target="_blank"} 💎 | | | | |
| | [Analyze PR Components](./tools/analyze.md){:target="_blank"} 💎 | ✔️ | ✔️ | ✔️ | ✔️ | | | [Analyze PR Components](./tools/analyze.md){:target="_blank"} 💎 | | | | |
| | | | | | | | | | | | | |
| USAGE | CLI | ✔️ | ✔️ | ✔️ | ✔️ | | USAGE | CLI | | | | |
| | App / webhook | ✔️ | ✔️ | | ✔️ | | | App / webhook | | | | |
| | Tagging bot | ✔️ | | | | | | Actions | | | | |
| | Actions | ✔️ | | | | | | | | | |
| | | | | | | CORE | PR compression | | ✅ | | |
| CORE | PR compression | ✔️ | ✔️ | ✔️ | ✔️ | | | Repo language prioritization | | | | |
| | Repo language prioritization | ✔️ | ✔️ | ✔️ | ✔️ | | | Adaptive and token-aware file patch fitting | | | | |
| | Adaptive and token-aware file patch fitting | ✔️ | ✔️ | ✔️ | ✔️ | | | Multiple models support | | | | |
| | Multiple models support | ✔️ | ✔️ | ✔️ | ✔️ | | | Incremental PR review | | | | |
| | Incremental PR review | ✔️ | | | | | | [Static code analysis](./tools/analyze.md/){:target="_blank"} 💎 | | | | |
| | [Static code analysis](./tools/analyze.md/){:target="_blank"} 💎 | ✔️ | ✔️ | ✔️ | ✔️ | | | [Multiple configuration options](./usage-guide/configuration_options.md){:target="_blank"} 💎 | | | | |
| | [Multiple configuration options](./usage-guide/configuration_options.md){:target="_blank"} 💎 | ✔️ | ✔️ | ✔️ | ✔️ |
💎 marks a feature available only in [PR-Agent Pro](https://www.codium.ai/pricing/){:target="_blank"} 💎 marks a feature available only in [PR-Agent Pro](https://www.codium.ai/pricing/){:target="_blank"}
## Example results ## Example Results
<hr>
<h4><a href="https://github.com/Codium-ai/pr-agent/pull/530">/describe</a></h4>
<div align="center">
<p float="center">
<img src="https://www.codium.ai/images/pr_agent/describe_new_short_main.png" width="512">
</p>
</div>
<hr> <hr>
<h4><a href="https://github.com/Codium-ai/pr-agent/pull/732#issuecomment-1975099151">/review</a></h4> #### [/describe](https://github.com/Codium-ai/pr-agent/pull/530)
<div align="center"> <figure markdown="1">
<p float="center"> ![/describe](https://www.codium.ai/images/pr_agent/describe_new_short_main.png){width=512}
<kbd> </figure>
<img src="https://www.codium.ai/images/pr_agent/review_new_short_main.png" width="512">
</kbd>
</p>
</div>
<hr> <hr>
<h4><a href="https://github.com/Codium-ai/pr-agent/pull/732#issuecomment-1975099159">/improve</a></h4> #### [/review](https://github.com/Codium-ai/pr-agent/pull/732#issuecomment-1975099151)
<div align="center"> <figure markdown="1">
<p float="center"> ![/review](https://www.codium.ai/images/pr_agent/review_new_short_main.png){width=512}
<kbd> </figure>
<img src="https://www.codium.ai/images/pr_agent/improve_new_short_main.png" width="512">
</kbd>
</p>
</div>
<hr> <hr>
<h4><a href="https://github.com/Codium-ai/pr-agent/pull/530">/generate_labels</a></h4> #### [/improve](https://github.com/Codium-ai/pr-agent/pull/732#issuecomment-1975099159)
<div align="center"> <figure markdown="1">
<p float="center"> ![/improve](https://www.codium.ai/images/pr_agent/improve_new_short_main.png){width=512}
<kbd><img src="https://www.codium.ai/images/pr_agent/geneare_custom_labels_main_short.png" width="300"></kbd> </figure>
</p>
</div>
[//]: # (<h4><a href="https://github.com/Codium-ai/pr-agent/pull/78#issuecomment-1639739496">/reflect_and_review:</a></h4>)
[//]: # (<div align="center">)
[//]: # (<p float="center">)
[//]: # (<img src="https://www.codium.ai/images/reflect_and_review.gif" width="800">)
[//]: # (</p>)
[//]: # (</div>)
[//]: # (<h4><a href="https://github.com/Codium-ai/pr-agent/pull/229#issuecomment-1695020538">/ask:</a></h4>)
[//]: # (<div align="center">)
[//]: # (<p float="center">)
[//]: # (<img src="https://www.codium.ai/images/ask-2.gif" width="800">)
[//]: # (</p>)
[//]: # (</div>)
[//]: # (<h4><a href="https://github.com/Codium-ai/pr-agent/pull/229#issuecomment-1695024952">/improve:</a></h4>)
[//]: # (<div align="center">)
[//]: # (<p float="center">)
[//]: # (<img src="https://www.codium.ai/images/improve-2.gif" width="800">)
[//]: # (</p>)
[//]: # (</div>)
<div align="left">
</div>
<hr> <hr>
#### [/generate_labels](https://github.com/Codium-ai/pr-agent/pull/530)
<figure markdown="1">
![/generate_labels](https://www.codium.ai/images/pr_agent/geneare_custom_labels_main_short.png){width=300}
</figure>
<hr>
## How it works ## How it Works
The following diagram illustrates PR-Agent tools and their flow: The following diagram illustrates PR-Agent tools and their flow:
@ -139,24 +86,39 @@ Check out the [PR Compression strategy](core-abilities/index.md) page for more d
[PR-Agent Pro](https://www.codium.ai/pricing/) is a hosted version of PR-Agent, provided by CodiumAI. It is available for a monthly fee, and provides the following benefits: [PR-Agent Pro](https://www.codium.ai/pricing/) is a hosted version of PR-Agent, provided by CodiumAI. It is available for a monthly fee, and provides the following benefits:
1. **Fully managed** - We take care of everything for you - hosting, models, regular updates, and more. Installation is as simple as signing up and adding the PR-Agent app to your GitHub\BitBucket repo. 1. **Fully managed** - We take care of everything for you - hosting, models, regular updates, and more. Installation is as simple as signing up and adding the PR-Agent app to your GitHub\GitLab\BitBucket repo.
2. **Improved privacy** - No data will be stored or used to train models. PR-Agent Pro will employ zero data retention, and will use an OpenAI account with zero data retention. 2. **Improved privacy** - No data will be stored or used to train models. PR-Agent Pro will employ zero data retention, and will use an OpenAI account with zero data retention.
3. **Improved support** - PR-Agent Pro users will receive priority support, and will be able to request new features and capabilities. 3. **Improved support** - PR-Agent Pro users will receive priority support, and will be able to request new features and capabilities.
4. **Extra features** -In addition to the benefits listed above, PR-Agent Pro will emphasize more customization, and the usage of static code analysis, in addition to LLM logic, to improve results. It has the following additional tools and features: 4. **Extra features** -In addition to the benefits listed above, PR-Agent Pro will emphasize more customization, and the usage of static code analysis, in addition to LLM logic, to improve results. It has the following additional tools and features:
- [**Analyze PR components**](./tools/analyze.md/) - (Tool): [**Analyze PR components**](./tools/analyze.md/)
- [**Custom Code Suggestions**](./tools/custom_suggestions.md/) - (Tool): [**Custom Prompt Suggestions**](./tools/custom_prompt.md/)
- [**Tests**](./tools/test.md/) - (Tool): [**Tests**](./tools/test.md/)
- [**PR documentation**](./tools/documentation.md/) - (Tool): [**PR documentation**](./tools/documentation.md/)
- [**CI feedback**](./tools/ci_feedback.md/) - (Tool): [**Improve Component**](https://pr-agent-docs.codium.ai/tools/improve_component/)
- [**SOC2 compliance check**](./tools/review.md/#soc2-ticket-compliance) - (Tool): [**Similar code search**](https://pr-agent-docs.codium.ai/tools/similar_code/)
- [**Custom labels**](./tools/describe.md/#handle-custom-labels-from-the-repos-labels-page) - (Tool): [**CI feedback**](./tools/ci_feedback.md/)
- [**Global and wiki configuration**](./usage-guide/configuration_options.md/#wiki-configuration-file) - (Feature): [**Interactive triggering**](./usage-guide/automations_and_usage.md/#interactive-triggering)
- (Feature): [**SOC2 compliance check**](./tools/review.md/#soc2-ticket-compliance)
- (Feature): [**Custom labels**](./tools/describe.md/#handle-custom-labels-from-the-repos-labels-page)
- (Feature): [**Global and wiki configuration**](./usage-guide/configuration_options.md/#wiki-configuration-file)
- (Feature): [**Inline file summary**](https://pr-agent-docs.codium.ai/tools/describe/#inline-file-summary)
## Data privacy ## Data Privacy
If you host PR-Agent with your OpenAI API key, it is between you and OpenAI. You can read their API data privacy policy here: ### Self-hosted PR-Agent
- If you host PR-Agent with your OpenAI API key, it is between you and OpenAI. You can read their API data privacy policy here:
https://openai.com/enterprise-privacy https://openai.com/enterprise-privacy
When using PR-Agent Pro 💎, hosted by CodiumAI, we will not store any of your data, nor will we use it for training. ### CodiumAI-hosted PR-Agent Pro 💎
You will also benefit from an OpenAI account with zero data retention.
- When using PR-Agent Pro 💎, hosted by CodiumAI, we will not store any of your data, nor will we use it for training. You will also benefit from an OpenAI account with zero data retention.
- For certain clients, CodiumAI-hosted PR-Agent Pro will use CodiumAIs proprietary models — if this is the case, you will be notified.
- No passive collection of Code and Pull Requests data — PR-Agent will be active only when you invoke it, and it will then extract and analyze only data relevant to the executed command and queried pull request.
### PR-Agent Chrome extension
- The [PR-Agent Chrome extension](https://chromewebstore.google.com/detail/pr-agent-chrome-extension/ephlnjeghhogofkifjloamocljapahnl) serves solely to modify the visual appearance of a GitHub PR screen. It does not transmit any user's repo or pull request code. Code is only sent for processing when a user submits a GitHub comment that activates a PR-Agent tool, in accordance with the standard privacy policy of PR-Agent.

View File

@ -4,16 +4,15 @@ To use Azure DevOps provider use the following settings in configuration.toml:
``` ```
[config] [config]
git_provider="azure" git_provider="azure"
use_repo_settings_file=false
``` ```
Azure DevOps provider supports [PAT token](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows) or [DefaultAzureCredential](https://learn.microsoft.com/en-us/azure/developer/python/sdk/authentication-overview#authentication-in-server-environments) authentication. Azure DevOps provider supports [PAT token](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows) or [DefaultAzureCredential](https://learn.microsoft.com/en-us/azure/developer/python/sdk/authentication-overview#authentication-in-server-environments) authentication.
PAT is faster to create, but has build in experation date, and will use the user identity for API calls. PAT is faster to create, but has build in expiration date, and will use the user identity for API calls.
Using DefaultAzureCredential you can use managed identity or Service principle, which are more secure and will create seperate ADO user identity (via AAD) to the agent. Using DefaultAzureCredential you can use managed identity or Service principle, which are more secure and will create separate ADO user identity (via AAD) to the agent.
If PAT was choosen, you can assign the value in .secrets.toml. If PAT was chosen, you can assign the value in .secrets.toml.
If DefaultAzureCredential was choosen, you can assigned the additional env vars like AZURE_CLIENT_SECRET directly, If DefaultAzureCredential was chosen, you can assigned the additional env vars like AZURE_CLIENT_SECRET directly,
or use managed identity/az cli (for local develpment) without any additional configuration. or use managed identity/az cli (for local development) without any additional configuration.
in any case, 'org' value must be assigned in .secrets.toml: in any case, 'org' value must be assigned in .secrets.toml:
``` ```
[azure_devops] [azure_devops]

View File

@ -7,9 +7,11 @@ You can use our pre-built Github Action Docker image to run PR-Agent as a Github
```yaml ```yaml
on: on:
pull_request: pull_request:
types: [opened, reopened, ready_for_review]
issue_comment: issue_comment:
jobs: jobs:
pr_agent_job: pr_agent_job:
if: ${{ github.event.sender.type != 'Bot' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
issues: write issues: write
@ -24,27 +26,14 @@ jobs:
OPENAI_KEY: ${{ secrets.OPENAI_KEY }} OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
``` ```
** if you want to pin your action to a specific release (v0.7 for example) for stability reasons, use: ** if you want to pin your action to a specific release (v2.0 for example) for stability reasons, use:
```yaml ```yaml
on: ...
pull_request:
issue_comment:
jobs:
pr_agent_job:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
contents: write
name: Run pr agent on every pull request, respond to user comments
steps: steps:
- name: PR Agent action step - name: PR Agent action step
id: pragent id: pragent
uses: Codium-ai/pr-agent@v0.7 uses: Codium-ai/pr-agent@v2.0
env: ...
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
``` ```
2) Add the following secret to your repository under `Settings > Secrets and variables > Actions > New repository secret > Add secret`: 2) Add the following secret to your repository under `Settings > Secrets and variables > Actions > New repository secret > Add secret`:
@ -66,6 +55,7 @@ When you open your next PR, you should see a comment from `github-actions` bot w
PR_REVIEWER.REQUIRE_TESTS_REVIEW: "false" # Disable tests review PR_REVIEWER.REQUIRE_TESTS_REVIEW: "false" # Disable tests review
PR_CODE_SUGGESTIONS.NUM_CODE_SUGGESTIONS: 6 # Increase number of code suggestions PR_CODE_SUGGESTIONS.NUM_CODE_SUGGESTIONS: 6 # Increase number of code suggestions
``` ```
See detailed usage instructions in the [USAGE GUIDE](https://pr-agent-docs.codium.ai/usage-guide/automations_and_usage/#github-action)
--- ---
@ -159,6 +149,9 @@ cp pr_agent/settings/.secrets_template.toml pr_agent/settings/.secrets.toml
## Deploy as a Lambda Function ## Deploy as a Lambda Function
Note that since AWS Lambda env vars cannot have "." in the name, you can replace each "." in an env variable with "__".<br>
For example: `GITHUB.WEBHOOK_SECRET` --> `GITHUB__WEBHOOK_SECRET`
1. Follow steps 1-5 from [here](#run-as-a-github-app). 1. Follow steps 1-5 from [here](#run-as-a-github-app).
2. Build a docker image that can be used as a lambda function 2. Build a docker image that can be used as a lambda function
```shell ```shell
@ -246,4 +239,4 @@ After you set up AWS CodeCommit using the instructions above, here is an example
PYTHONPATH="/PATH/TO/PROJECTS/pr-agent" python pr_agent/cli.py \ PYTHONPATH="/PATH/TO/PROJECTS/pr-agent" python pr_agent/cli.py \
--pr_url https://us-east-1.console.aws.amazon.com/codesuite/codecommit/repositories/MY_REPO_NAME/pull-requests/321 \ --pr_url https://us-east-1.console.aws.amazon.com/codesuite/codecommit/repositories/MY_REPO_NAME/pull-requests/321 \
review review
``` ```

View File

@ -1,5 +1,6 @@
# Installation # Installation
## Self-hosted PR-Agent
If you choose to host you own PR-Agent, you first need to acquire two tokens: If you choose to host you own PR-Agent, you first need to acquire two tokens:
1. An OpenAI key from [here](https://platform.openai.com/api-keys), with access to GPT-4 (or a key for [other models](../usage-guide/additional_configurations.md/#changing-a-model), if you prefer). 1. An OpenAI key from [here](https://platform.openai.com/api-keys), with access to GPT-4 (or a key for [other models](../usage-guide/additional_configurations.md/#changing-a-model), if you prefer).
@ -13,7 +14,9 @@ There are several ways to use self-hosted PR-Agent:
- [BitBucket](./bitbucket.md) - [BitBucket](./bitbucket.md)
- [Azure DevOps](./azure.md) - [Azure DevOps](./azure.md)
___ ## PR-Agent Pro 💎
Note that [PR-Agent Pro 💎](https://app.codium.ai/), an app for GitHub\GitLab\BitBucket hosted by CodiumAI, is also available. PR-Agent Pro, an app for GitHub\GitLab\BitBucket hosted by CodiumAI, is also available.
<br> <br>
With PR-Agent Pro Installation is as simple as signing up and adding the PR-Agent app to your relevant repo. With PR-Agent Pro Installation is as simple as signing up and adding the PR-Agent app to your relevant repo.
<br>
See [here](./pr_agent_pro.md) for more details.

View File

@ -1,4 +1,41 @@
## Use Docker image (no installation required) ## Using pip package
Install the package:
```
pip install pr-agent
```
Then run the relevant tool with the script below.
<br>
Make sure to fill in the required parameters (`user_token`, `openai_key`, `pr_url`, `command`):
```python
from pr_agent import cli
from pr_agent.config_loader import get_settings
def main():
# Fill in the following values
provider = "github" # GitHub provider
user_token = "..." # GitHub user token
openai_key = "..." # OpenAI key
pr_url = "..." # PR URL, for example 'https://github.com/Codium-ai/pr-agent/pull/809'
command = "/review" # Command to run (e.g. '/review', '/describe', '/ask="What is the purpose of this PR?"', ...)
# Setting the configurations
get_settings().set("CONFIG.git_provider", provider)
get_settings().set("openai.key", openai_key)
get_settings().set("github.user_token", user_token)
# Run the command. Feedback will appear in GitHub PR comments
cli.run_command(pr_url, command)
if __name__ == '__main__':
main()
```
## Using Docker image
A list of the relevant tools can be found in the [tools guide](../tools/ask.md). A list of the relevant tools can be found in the [tools guide](../tools/ask.md).

View File

@ -0,0 +1,64 @@
## Getting Started with PR-Agent Pro
PR-Agent Pro is a versatile application compatible with GitHub, GitLab, and BitBucket, hosted by CodiumAI.
See [here](https://pr-agent-docs.codium.ai/#pr-agent-pro) for more details about the benefits of using PR-Agent Pro.
Interested parties can subscribe to PR-Agent Pro through the following [link](https://www.codium.ai/pricing/).
After subscribing, you are granted the ability to easily install the application across any of your repositories.
![PR Agent Pro](https://codium.ai/images/pr_agent/pr_agent_pro_install.png){width=468}
Each user who wants to use PR-Agent pro needs to buy a seat.
Initially, CodiumAI offers a two-week trial period at no cost, after which continued access requires each user to secure a personal seat.
Once a user acquires a seat, they gain the flexibility to use PR-Agent Pro across any repository where it was enabled.
Users without a purchased seat who interact with a repository featuring PR-Agent Pro are entitled to receive up to five complimentary feedbacks.
Beyond this limit, PR-Agent Pro will cease to respond to their inquiries unless a seat is purchased.
## Install PR-Agent Pro for GitLab (Teams & Enterprise)
Since GitLab platform does not support apps, installing PR-Agent Pro for GitLab is a bit more involved, and requires the following steps:
### Step 1
Acquire a personal, project or group level access token. Enable the “api” scope in order to allow PR-Agent to read pull requests, comment and respond to requests.
<figure markdown="1">
![Step 1](https://www.codium.ai/images/pr_agent/gitlab_pro_pat.png){width=750}
</figure>
Store the token in a safe place, you wont be able to access it again after it was generated.
### Step 2
Generate a shared secret and link it to the access token. Browse to [https://register.gitlab.pr-agent.codium.ai](https://register.gitlab.pr-agent.codium.ai).
Fill in your generated GitLab token and your company or personal name in the appropriate fields and click "Submit".
You should see "Success!" displayed above the Submit button, and a shared secret will be generated. Store it in a safe place, you wont be able to access it again after it was generated.
### Step 3
Install a webhook for your repository or groups, by clicking “webhooks” on the settings menu. Click the “Add new webhook” button.
<figure markdown="1">
![Step 3.1](https://www.codium.ai/images/pr_agent/gitlab_pro_add_webhook.png)
</figure>
In the webhook definition form, fill in the following fields:
URL: https://pro.gitlab.pr-agent.codium.ai/webhook
Secret token: Your CodiumAI key
Trigger: Check the comments and merge request events boxes.
Enable SSL verification: Check the box.
<figure markdown="1">
![Step 3.2](https://www.codium.ai/images/pr_agent/gitlab_pro_webhooks.png){width=750}
</figure>
### Step 4
Youre all set!
Open a new merge request or add a MR comment with one of PR-Agents commands such as /review, /describe or /improve.

View File

@ -1,7 +1,7 @@
## Overview ## Overview
The `analyze` tool combines static code analysis with LLM capabilities to provide a comprehensive analysis of the PR code changes. The `analyze` tool combines advanced static code analysis with LLM capabilities to provide a comprehensive analysis of the PR code changes.
The tool scans the PR code changes, find the code components (methods, functions, classes) that changed, and summarizes the changes in each component. The tool scans the PR code changes, find the code components (methods, functions, classes) that changed, and enables to interactively generate tests, docs, code suggestions and similar code search for each component.
It can be invoked manually by commenting on any PR: It can be invoked manually by commenting on any PR:
``` ```
@ -9,16 +9,11 @@ It can be invoked manually by commenting on any PR:
``` ```
## Example usage ## Example usage
An example [result](https://github.com/Codium-ai/pr-agent/pull/546#issuecomment-1868524805):
<kbd><img src=https://codium.ai/images/pr_agent/analyze_1.png width="768"></kbd>
<kbd><img src=https://codium.ai/images/pr_agent/analyze_2.png width="768"></kbd>
<kbd><img src=https://codium.ai/images/pr_agent/analyze_3.png width="768"></kbd>
An example result:
![Analyze 1](https://codium.ai/images/pr_agent/analyze_1.png){width=750}
**Notes** **Notes**
- Language that are currently supported: Python, Java, C++, JavaScript, TypeScript. - Language that are currently supported: Python, Java, C++, JavaScript, TypeScript, C#.

View File

@ -5,11 +5,12 @@ It can be invoked manually by commenting on any PR:
``` ```
/ask "..." /ask "..."
``` ```
For example:
<kbd><img src="https://codium.ai/images/pr_agent/ask_comment.png" width="768"></kbd> ## Example usage
<kbd><img src="https://codium.ai/images/pr_agent/ask.png" width="768"></kbd> ![Ask Comment](https://codium.ai/images/pr_agent/ask_comment.png){width=512}
![Ask](https://codium.ai/images/pr_agent/ask.png){width=512}
## Ask lines ## Ask lines
@ -18,6 +19,41 @@ You can run `/ask` on specific lines of code in the PR from the PR's diff view.
- To select multiple lines, click on the '+' sign of the first line and then hold and drag to select the rest of the lines. - To select multiple lines, click on the '+' sign of the first line and then hold and drag to select the rest of the lines.
- write `/ask "..."` in the comment box and press `Add single comment` button. - write `/ask "..."` in the comment box and press `Add single comment` button.
<kbd><img src="https://codium.ai/images/pr_agent/Ask_line.png" width="768"></kbd> ![Ask Line](https://codium.ai/images/pr_agent/Ask_line.png){width=512}
Note that the tool does not have "memory" of previous questions, and answers each question independently. Note that the tool does not have "memory" of previous questions, and answers each question independently.
## Ask on images
You can also ask questions about images that appear in the comment, where the entire PR code will be used as context.
<br>
The basic syntax is:
```
/ask "..."
[Image](https://real_link_to_image)
```
where `https://real_link_to_image` is the direct link to the image.
Note that GitHub has a built-in mechanism of pasting images in comments. However, pasted image does not provide a direct link.
To get a direct link to an image, we recommend using the following scheme:
1) First, post a comment that contains **only** the image:
![Ask image1](https://codium.ai/images/pr_agent/ask_images1.png){width=512}
2) Quote reply to that comment:
![Ask image2](https://codium.ai/images/pr_agent/ask_images2.png){width=512}
3) In the screen opened, type the question below the image:
![Ask image3](https://codium.ai/images/pr_agent/ask_images3.png){width=512}
![Ask image4](https://codium.ai/images/pr_agent/ask_images4.png){width=512}
4) Post the comment, and receive the answer:
![Ask image5](https://codium.ai/images/pr_agent/ask_images5.png){width=512}
See a full video tutorial [here](https://codium.ai/images/pr_agent/ask_image_video.mov)

View File

@ -8,13 +8,12 @@ The tool analyzes the failed checks and provides several feedbacks:
- Failure summary - Failure summary
- Relevant error logs - Relevant error logs
<kbd> ## Example usage
<img src="https://www.codium.ai/images/pr_agent/failed_check1.png" width="768">
</kbd> ![Failed Check 1](https://www.codium.ai/images/pr_agent/failed_check1.png){width=768}
&rarr; &rarr;
<kbd> ![Failed Check 2](https://www.codium.ai/images/pr_agent/failed_check2.png){width=768}
<img src="https://www.codium.ai/images/pr_agent/failed_check2.png" width="768">
</kbd>
___ ___
@ -24,6 +23,14 @@ In addition to being automatically triggered, the tool can also be invoked manua
``` ```
where `{repo_name}` is the name of the repository, `{run_number}` is the run number of the failed check, and `{job_number}` is the job number of the failed check. where `{repo_name}` is the name of the repository, `{run_number}` is the run number of the failed check, and `{job_number}` is the job number of the failed check.
## Disabling the tool from running automatically
If you wish to disable the tool from running automatically, you can do so by adding the following configuration to the configuration file:
```
[checks]
enable_auto_checks_feedback = false
```
## Configuration options ## Configuration options
- `enable_auto_checks_feedback` - if set to true, the tool will automatically provide feedback when a check is failed. Default is true. - `enable_auto_checks_feedback` - if set to true, the tool will automatically provide feedback when a check is failed. Default is true.
- `excluded_checks_list` - a list of checks to exclude from the feedback, for example: ["check1", "check2"]. Default is an empty list. - `excluded_checks_list` - a list of checks to exclude from the feedback, for example: ["check1", "check2"]. Default is an empty list.

View File

@ -5,15 +5,16 @@ It can be invoked manually by commenting on any PR:
``` ```
/generate_labels /generate_labels
``` ```
For example:
## Example usage
If we wish to add detect changes to SQL queries in a given PR, we can add the following custom label along with its description: If we wish to add detect changes to SQL queries in a given PR, we can add the following custom label along with its description:
<kbd><img src=https://codium.ai/images/pr_agent/custom_labels_list.png width="768"></kbd> ![Custom labels list](https://codium.ai/images/pr_agent/custom_labels_list.png){width=768}
When running the `generate_labels` tool on a PR that includes changes in SQL queries, it will automatically suggest the custom label: When running the `generate_labels` tool on a PR that includes changes in SQL queries, it will automatically suggest the custom label:
<kbd><img src=https://codium.ai/images/pr_agent/custom_label_published.png width="768"></kbd> ![Custom labels published](https://codium.ai/images/pr_agent/custom_label_published.png){width=768}
Note that in addition to the dedicated tool `generate_labels`, the custom labels will also be used by the `describe` tool. Note that in addition to the dedicated tool `generate_labels`, the custom labels will also be used by the `describe` tool.
@ -36,7 +37,8 @@ b. Add/edit the custom labels. It should be formatted as follows:
* Label name: The name of the custom label. * Label name: The name of the custom label.
* Description: Start the description of with prefix `pr_agent:`, for example: `pr_agent: Description of when AI should suggest this label`.<br> * Description: Start the description of with prefix `pr_agent:`, for example: `pr_agent: Description of when AI should suggest this label`.<br>
The description should be comprehensive and detailed, indicating when to add the desired label. The description should be comprehensive and detailed, indicating when to add the desired label.
<kbd><img src=https://codium.ai/images/pr_agent/add_native_custom_labels.png width="880"></kbd>
![Add native custom labels](https://codium.ai/images/pr_agent/add_native_custom_labels.png){width=880}
c. Now the custom labels will be included in the `generate_labels` tool. c. Now the custom labels will be included in the `generate_labels` tool.

View File

@ -0,0 +1,58 @@
## Overview
The `custom_prompt` tool scans the PR code changes, and automatically generates suggestions for improving the PR code.
It shares similarities with the `improve` tool, but with one main difference: the `custom_prompt` tool will **only propose suggestions that follow specific guidelines defined by the prompt** in: `pr_custom_prompt.prompt` configuration.
The tool can be triggered [automatically](../usage-guide/automations_and_usage.md#github-app-automatic-tools-when-a-new-pr-is-opened) every time a new PR is opened, or can be invoked manually by commenting on a PR.
When commenting, use the following template:
```
/custom_prompt --pr_custom_prompt.prompt="
The code suggestions should focus only on the following:
- ...
- ...
"
```
With a [configuration file](../usage-guide/automations_and_usage.md#github-app), use the following template:
```
[pr_custom_prompt]
prompt="""\
The suggestions should focus only on the following:
-...
-...
"""
```
Remember - with this tool, you are the prompter. Be specific, clear, and concise in the instructions. Specify relevant aspects that you want the model to focus on. \
You might benefit from several trial-and-error iterations, until you get the correct prompt for your use case.
## Example usage
Here is an example of a possible prompt, defined in the configuration file:
```
[pr_custom_prompt]
prompt="""\
The code suggestions should focus only on the following:
- look for edge cases when implementing a new function
- make sure every variable has a meaningful name
- make sure the code is efficient
"""
```
(The instructions above are just an example. We want to emphasize that the prompt should be specific and clear, and be tailored to the needs of your project)
Results obtained with the prompt above:
![Custom prompt results](https://codium.ai/images/pr_agent/custom_suggestions_result.png){width=768}
## Configuration options
`prompt`: the prompt for the tool. It should be a multi-line string.
`num_code_suggestions`: number of code suggestions provided by the 'custom_prompt' tool. Default is 4.
`enable_help_text`: if set to true, the tool will display a help text in the comment. Default is true.

View File

@ -1,57 +0,0 @@
## Overview
The `custom_suggestions` tool scans the PR code changes, and automatically generates custom suggestions for improving the PR code.
It shares similarities with the `improve` tool, but with one main difference: the `custom_suggestions` tool will only propose suggestions that follow specific guidelines defined by the prompt in: `pr_custom_suggestions.prompt` configuration.
The tool can be triggered [automatically](../usage-guide/automations_and_usage.md#github-app-automatic-tools-when-a-new-pr-is-opened) every time a new PR is opened, or can be invoked manually by commenting on a PR.
When commenting, use the following template:
```
/custom_suggestions --pr_custom_suggestions.prompt="The suggestions should focus only on the following:\n-...\n-...\n-..."
```
With a [configuration file](../usage-guide/automations_and_usage.md#github-app), use the following template:
```
[pr_custom_suggestions]
prompt="""\
The suggestions should focus only on the following:
-...
-...
-...
"""
```
Using a configuration file is recommended, since it allows to use multi-line instructions.
Don't forget - with this tool, you are the prompter. Be specific, clear, and concise in the instructions. Specify relevant aspects that you want the model to focus on. \
You might benefit from several trial-and-error iterations, until you get the correct prompt for your use case.
## Example usage
Here is an example of a possible prompt:
```
[pr_custom_suggestions]
prompt="""\
The suggestions should focus only on the following:
- look for edge cases when implementing a new function
- make sure every variable has a meaningful name
- make sure the code is efficient
"""
```
The instructions above are just an example. We want to emphasize that the prompt should be specific and clear, and be tailored to the needs of your project.
Results obtained with the prompt above:
<kbd><img src=https://codium.ai/images/pr_agent/custom_suggestions_prompt.png width="512"></kbd>
<kbd><img src=https://codium.ai/images/pr_agent/custom_suggestions_result.png width="768"></kbd>
## Configuration options
`prompt`: the prompt for the tool. It should be a multi-line string.
`num_code_suggestions`: number of code suggestions provided by the 'custom_suggestions' tool. Default is 4.
`enable_help_text`: if set to true, the tool will display a help text in the comment. Default is true.

View File

@ -5,80 +5,119 @@ The tool can be triggered automatically every time a new PR is [opened](../usage
``` ```
/describe /describe
``` ```
For example:
<kbd><img src=https://codium.ai/images/pr_agent/describe_comment.png width="768"></kbd> ## Example usage
<kbd><img src=https://codium.ai/images/pr_agent/describe_new.png width="768"></kbd> ### Manual triggering
Invoke the tool manually by commenting `/describe` on any PR:
![Describe comment](https://codium.ai/images/pr_agent/describe_comment.png){width=512}
## Configuration options
To edit [configurations](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L46) related to the describe tool (`pr_description` section), use the following template: After ~30 seconds, the tool will generate a description for the PR:
![Describe New](https://codium.ai/images/pr_agent/describe_new.png){width=512}
If you want to edit [configurations](#configuration-options), add the relevant ones to the command:
``` ```
/describe --pr_description.some_config1=... --pr_description.some_config2=... /describe --pr_description.some_config1=... --pr_description.some_config2=...
``` ```
### Possible configurations: ### Automatic triggering
- `publish_labels`: if set to true, the tool will publish the labels to the PR. Default is true. To run the `describe` automatically when a PR is opened, define in a [configuration file](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/#wiki-configuration-file):
```
[github_app]
pr_commands = [
"/describe",
...
]
- `publish_description_as_comment`: if set to true, the tool will publish the description as a comment to the PR. If false, it will overwrite the origianl description. Default is false. [pr_description]
publish_labels = ...
...
```
- `add_original_user_description`: if set to true, the tool will add the original user description to the generated description. Default is true. - The `pr_commands` lists commands that will be executed automatically when a PR is opened.
- The `[pr_description]` section contains the configurations for the `describe` tool you want to edit (if any).
- `keep_original_user_title`: if set to true, the tool will keep the original PR title, and won't change it. Default is true.
- `extra_instructions`: Optional extra instructions to the tool. For example: "focus on the changes in the file X. Ignore change in ...". ## Configuration options
- To enable `custom labels`, apply the configuration changes described [here](./custom_labels.md#configuration-options) !!! example "Possible configurations"
- `enable_pr_type`: if set to false, it will not show the `PR type` as a text value in the description content. Default is true. <table>
<tr>
<td><b>publish_labels</b></td>
<td>If set to true, the tool will publish the labels to the PR. Default is true.</td>
</tr>
<tr>
<td><b>publish_description_as_comment</b></td>
<td>If set to true, the tool will publish the description as a comment to the PR. If false, it will overwrite the original description. Default is false.</td>
</tr>
<tr>
<td><b>publish_description_as_comment_persistent</b></td>
<td>If set to true and `publish_description_as_comment` is true, the tool will publish the description as a persistent comment to the PR. Default is true.</td>
</tr>
<tr>
<td><b>add_original_user_description</b></td>
<td>If set to true, the tool will add the original user description to the generated description. Default is true.</td>
</tr>
<tr>
<td><b>generate_ai_title</b></td>
<td>If set to true, the tool will also generate an AI title for the PR. Default is false.</td>
</tr>
<tr>
<td><b>extra_instructions</b></td>
<td>Optional extra instructions to the tool. For example: "focus on the changes in the file X. Ignore change in ..."</td>
</tr>
<tr>
<td><b>enable_pr_type</b></td>
<td>If set to false, it will not show the `PR type` as a text value in the description content. Default is true.</td>
</tr>
<tr>
<td><b>final_update_message</b></td>
<td>If set to true, it will add a comment message [`PR Description updated to latest commit...`](https://github.com/Codium-ai/pr-agent/pull/499#issuecomment-1837412176) after finishing calling `/describe`. Default is true.</td>
</tr>
<tr>
<td><b>enable_semantic_files_types</b></td>
<td>If set to true, "Changes walkthrough" section will be generated. Default is true.</td>
</tr>
<tr>
<td><b>collapsible_file_list</b></td>
<td>If set to true, the file list in the "Changes walkthrough" section will be collapsible. If set to "adaptive", the file list will be collapsible only if there are more than 8 files. Default is "adaptive".</td>
</tr>
<tr>
<td><b>enable_help_text</b></td>
<td>If set to true, the tool will display a help text in the comment. Default is false.</td>
</tr>
</table>
- `final_update_message`: if set to true, it will add a comment message [`PR Description updated to latest commit...`](https://github.com/Codium-ai/pr-agent/pull/499#issuecomment-1837412176) after finishing calling `/describe`. Default is true.
- `enable_semantic_files_types`: if set to true, "Changes walkthrough" section will be generated. Default is true. ## Inline file summary 💎
- `collapsible_file_list`: if set to true, the file list in the "Changes walkthrough" section will be collapsible. If set to "adaptive", the file list will be collapsible only if there are more than 8 files. Default is "adaptive".
### Inline file summary 💎
> This feature is available only in PR-Agent Pro
This feature will enable you to quickly understand the changes in each file while reviewing the code changes (diff view). This feature enables you to copy the `changes walkthrough` table to the "Files changed" tab, so you can quickly understand the changes in each file while reviewing the code changes (diff view).
To add the walkthrough table to the "Files changed" tab, you can click on the checkbox that appears PR Description status message below the main PR Description: To copy the `changes walkthrough` table to the "Files changed" tab, you can click on the checkbox that appears PR Description status message below the main PR Description:
<kbd><img src=https://codium.ai/images/pr_agent/add_table_checkbox.png width="512"></kbd> ![Add table checkbox](https://codium.ai/images/pr_agent/add_table_checkbox.png){width=512}
If you prefer to have the file summaries appear in the "Files changed" tab on every PR, change the `pr_description.inline_file_summary` parameter in the configuration file, possible values are: If you prefer to have the file summaries appear in the "Files changed" tab on every PR, change the `pr_description.inline_file_summary` parameter in the configuration file, possible values are:
- `'table'`: File changes walkthrough table will be displayed on the top of the "Files changed" tab, in addition to the "Conversation" tab. - `'table'`: File changes walkthrough table will be displayed on the top of the "Files changed" tab, in addition to the "Conversation" tab.
<kbd><img src=https://codium.ai/images/pr_agent/diffview-table.png width="768"></kbd>
![Diffview table](https://codium.ai/images/pr_agent/diffview-table.png){width=512}
- `true`: A collapsable file comment with changes title and a changes summary for each file in the PR. - `true`: A collapsable file comment with changes title and a changes summary for each file in the PR.
<kbd><img src=https://codium.ai/images/pr_agent/diffview_changes.png width="768"></kbd>
![Diffview changes](https://codium.ai/images/pr_agent/diffview_changes.png){width=512}
- `false` (`default`): File changes walkthrough will be added only to the "Conversation" tab. - `false` (`default`): File changes walkthrough will be added only to the "Conversation" tab.
**Note** that this feature is currently available only for GitHub. **Note**: that this feature is currently available only for GitHub.
### Handle custom labels from the Repo's labels page 💎 ## Markers template
> This feature is available only in PR-Agent Pro
You can control the custom labels that will be suggested by the `describe` tool, from the repo's labels page:
* GitHub : go to `https://github.com/{owner}/{repo}/labels` (or click on the "Labels" tab in the issues or PRs page)
* GitLab : go to `https://gitlab.com/{owner}/{repo}/-/labels` (or click on "Manage" -> "Labels" on the left menu)
Now add/edit the custom labels. they should be formatted as follows:
* Label name: The name of the custom label.
* Description: Start the description of with prefix `pr_agent:`, for example: `pr_agent: Description of when AI should suggest this label`.<br>
The description should be comprehensive and detailed, indicating when to add the desired label. For example:
<kbd><img src=https://codium.ai/images/pr_agent/add_native_custom_labels.png width="880"></kbd>
### Markers template
To enable markers, set `pr_description.use_description_markers=true`. To enable markers, set `pr_description.use_description_markers=true`.
Markers enable to easily integrate user's content and auto-generated content, with a template-like mechanism. Markers enable to easily integrate user's content and auto-generated content, with a template-like mechanism.
@ -98,56 +137,73 @@ pr_agent:walkthrough
``` ```
The marker `pr_agent:type` will be replaced with the PR type, `pr_agent:summary` will be replaced with the PR summary, and `pr_agent:walkthrough` will be replaced with the PR walkthrough. The marker `pr_agent:type` will be replaced with the PR type, `pr_agent:summary` will be replaced with the PR summary, and `pr_agent:walkthrough` will be replaced with the PR walkthrough.
<kbd><img src=https://codium.ai/images/pr_agent/describe_markers_before.png width="768"></kbd> ![Describe markers before](https://codium.ai/images/pr_agent/describe_markers_before.png){width=512}
&rarr;
<kbd><img src=https://codium.ai/images/pr_agent/describe_markers_after.png width="768"></kbd>
### Configuration params: &rarr;
![Describe markers after](https://codium.ai/images/pr_agent/describe_markers_after.png){width=512}
**Configuration params**:
- `use_description_markers`: if set to true, the tool will use markers template. It replaces every marker of the form `pr_agent:marker_name` with the relevant content. Default is false. - `use_description_markers`: if set to true, the tool will use markers template. It replaces every marker of the form `pr_agent:marker_name` with the relevant content. Default is false.
- `include_generated_by_header`: if set to true, the tool will add a dedicated header: 'Generated by PR Agent at ...' to any automatic content. Default is true. - `include_generated_by_header`: if set to true, the tool will add a dedicated header: 'Generated by PR Agent at ...' to any automatic content. Default is true.
## Custom labels
## Usage Tips
### Automation
- When you first install the app, the [default mode](../usage-guide/automations_and_usage.md#github-app) for the describe tool is:
```
pr_commands = ["/describe --pr_description.add_original_user_description=true"
"--pr_description.keep_original_user_title=true", ...]
```
meaning the `describe` tool will run automatically on every PR, will keep the original title, and will add the original user description above the generated description.
<br> This default settings aim to strike a good balance between automation and control:
If you want more automation, just give the PR a title, and the tool will auto-write a full description; If you want more control, you can add a detailed description, and the tool will add the complementary description below it.
- For maximal automation, you can change the default mode to:
```
pr_commands = ["/describe --pr_description.add_original_user_description=false"
"--pr_description.keep_original_user_title=true", ...]
```
so the title will be auto-generated as well.
- Markers are an alternative way to control the generated description, to give maximal control to the user. If you set:
```
pr_commands = ["/describe --pr_description.use_description_markers=true", ...]
```
the tool will replace every marker of the form `pr_agent:marker_name` in the PR description with the relevant content, where `marker_name` is one of the following:
- `type`: the PR type.
- `summary`: the PR summary.
- `walkthrough`: the PR walkthrough.
Note that when markers are enabled, if the original PR description does not contain any markers, the tool will not alter the description at all.
### Custom labels
The default labels of the describe tool are quite generic, since they are meant to be used in any repo: [`Bug fix`, `Tests`, `Enhancement`, `Documentation`, `Other`]. The default labels of the describe tool are quite generic, since they are meant to be used in any repo: [`Bug fix`, `Tests`, `Enhancement`, `Documentation`, `Other`].
If you specify [custom labels](#handle-custom-labels-from-the-repos-labels-page) in the repo's labels page, you can get tailored labels for your use cases. You can define custom labels that are relevant for your repo and use cases.
Custom labels can be defined in a [configuration file](https://pr-agent-docs.codium.ai/tools/custom_labels/#configuration-options), or directly in the repo's [labels page](#handle-custom-labels-from-the-repos-labels-page).
Examples for custom labels: Examples for custom labels:
- `Main topic:performance` - pr_agent:The main topic of this PR is performance
- `New endpoint` - pr_agent:A new endpoint was added in this PR - `Main topic:performance` - pr_agent:The main topic of this PR is performance
- `SQL query` - pr_agent:A new SQL query was added in this PR - `New endpoint` - pr_agent:A new endpoint was added in this PR
- `Dockerfile changes` - pr_agent:The PR contains changes in the Dockerfile - `SQL query` - pr_agent:A new SQL query was added in this PR
- ... - `Dockerfile changes` - pr_agent:The PR contains changes in the Dockerfile
- ...
The list above is eclectic, and aims to give an idea of different possibilities. Define custom labels that are relevant for your repo and use cases. The list above is eclectic, and aims to give an idea of different possibilities. Define custom labels that are relevant for your repo and use cases.
Note that Labels are not mutually exclusive, so you can add multiple label categories. Note that Labels are not mutually exclusive, so you can add multiple label categories.
<br>Make sure to provide proper title, and a detailed and well-phrased description for each label, so the tool will know when to suggest it. <br>
Make sure to provide proper title, and a detailed and well-phrased description for each label, so the tool will know when to suggest it.
Each label description should be a **conditional statement**, that indicates if to add the label to the PR or not, according to the PR content.
### Handle custom labels from the Repo's labels page 💎
You can control the custom labels that will be suggested by the `describe` tool, from the repo's labels page:
* GitHub : go to `https://github.com/{owner}/{repo}/labels` (or click on the "Labels" tab in the issues or PRs page)
* GitLab : go to `https://gitlab.com/{owner}/{repo}/-/labels` (or click on "Manage" -> "Labels" on the left menu)
Now add/edit the custom labels. they should be formatted as follows:
* Label name: The name of the custom label.
* Description: Start the description of with prefix `pr_agent:`, for example: `pr_agent: Description of when AI should suggest this label`.<br>
The description should be comprehensive and detailed, indicating when to add the desired label. For example:
![Add native custom labels](https://codium.ai/images/pr_agent/add_native_custom_labels.png){width=768}
## Usage Tips
!!! tip "Automation"
- When you first install PR-Agent app, the [default mode](../usage-guide/automations_and_usage.md#github-app) for the describe tool is:
```
pr_commands = ["/describe", ...]
```
meaning the `describe` tool will run automatically on every PR, with the default configurations.
- Markers are an alternative way to control the generated description, to give maximal control to the user. If you set:
```
pr_commands = ["/describe --pr_description.use_description_markers=true", ...]
```
the tool will replace every marker of the form `pr_agent:marker_name` in the PR description with the relevant content, where `marker_name` is one of the following:
* `type`: the PR type.
* `summary`: the PR summary.
* `walkthrough`: the PR walkthrough.
- Note that when markers are enabled, if the original PR description does not contain any markers, the tool will not alter the description at all.

View File

@ -5,13 +5,23 @@ It can be invoked manually by commenting on any PR:
``` ```
/add_docs /add_docs
``` ```
For example:
<kbd><img src=https://codium.ai/images/pr_agent/docs_command.png width="768"></kbd> ## Example usage
<kbd><img src=https://codium.ai/images/pr_agent/docs_components.png width="768"></kbd> Invoke the tool manually by commenting `/add_docs` on any PR:
<kbd><img src=https://codium.ai/images/pr_agent/docs_single_component.png width="768"></kbd> ![Docs command](https://codium.ai/images/pr_agent/docs_command.png){width=768}
The tool will generate documentation for all the components that changed in the PR:
![Docs component](https://codium.ai/images/pr_agent/docs_components.png){width=768}
![Docs single component](https://codium.ai/images/pr_agent/docs_single_component.png){width=768}
You can state a name of a specific component in the PR to get documentation only for that component:
```
/add_docs component_name
```
## Configuration options ## Configuration options
- `docs_style`: The exact style of the documentation (for python docstring). you can choose between: `google`, `numpy`, `sphinx`, `restructuredtext`, `plain`. Default is `sphinx`. - `docs_style`: The exact style of the documentation (for python docstring). you can choose between: `google`, `numpy`, `sphinx`, `restructuredtext`, `plain`. Default is `sphinx`.
@ -19,6 +29,5 @@ For example:
**Notes** **Notes**
- Language that are currently fully supported: Python, Java, C++, JavaScript, TypeScript. - Language that are currently fully supported: Python, Java, C++, JavaScript, TypeScript, C#.
- For languages that are not fully supported, the tool will suggest documentation only for new components in the PR. - This tool can also be triggered interactively by using the [`analyze`](./analyze.md) tool.
- A previous version of the tool, that offered support only for new components, was deprecated.

17
docs/docs/tools/help.md Normal file
View File

@ -0,0 +1,17 @@
## Overview
The `help` tool provides a list of all the available tools and their descriptions.
For PR-Agent Pro users, it also enables to trigger each tool by checking the relevant box.
It can be invoked manually by commenting on any PR:
```
/help
```
## Example usage
An example [result](https://github.com/Codium-ai/pr-agent/pull/546#issuecomment-1868524805):
![Help 1](https://codium.ai/images/pr_agent/help1.png){width=750}
&rarr;
![Analyze 2](https://codium.ai/images/pr_agent/help2.png){width=750}

View File

@ -5,85 +5,163 @@ The tool can be triggered automatically every time a new PR is [opened](../usage
/improve /improve
``` ```
### Summarized vs committable code suggestions ## Example usage
The code suggestions can be presented as a single comment (via `pr_code_suggestions.summarize=true`): ### Manual triggering
<kbd><img src=https://codium.ai/images/pr_agent/code_suggestions_as_comment.png width="768"></kbd> Invoke the tool manually by commenting `/improve` on any PR. The code suggestions by default are presented as a single comment:
![code suggestions as comment](https://codium.ai/images/pr_agent/code_suggestions_as_comment.png){width=512}
Or as a separate commitable code comment for each suggestion: To edit [configurations](#configuration-options) related to the improve tool, use the following template:
<kbd><img src=https://codium.ai/images/pr_agent/improve.png width="768"></kbd>
Note that a single comment has a significantly smaller PR footprint. We recommend this mode for most cases.
Also note that collapsible are not supported in _Bitbucket_. Hence, the suggestions are presented there as code comments.
### Extended mode
An extended mode, which does not involve PR Compression and provides more comprehensive suggestions, can be invoked by commenting on any PR:
```
/improve --extended
```
or by setting:
```
[pr_code_suggestions]
auto_extended_mode=true
```
(True by default).
Note that the extended mode divides the PR code changes into chunks, up to the token limits, where each chunk is handled separately (might use multiple calls to GPT-4 for large PRs).
Hence, the total number of suggestions is proportional to the number of chunks, i.e., the size of the PR.
### Configuration options
To edit [configurations](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L66) related to the improve tool (`pr_code_suggestions` section), use the following template:
``` ```
/improve --pr_code_suggestions.some_config1=... --pr_code_suggestions.some_config2=... /improve --pr_code_suggestions.some_config1=... --pr_code_suggestions.some_config2=...
``` ```
### General options For example, you can choose to present the suggestions as commitable code comments, by running the following command:
```
/improve --pr_code_suggestions.commitable_code_suggestions=true
```
- `num_code_suggestions`: number of code suggestions provided by the 'improve' tool. Default is 4. ![improve](https://codium.ai/images/pr_agent/improve.png){width=512}
- `extra_instructions`: Optional extra instructions to the tool. For example: "focus on the changes in the file X. Ignore change in ...".
- `rank_suggestions`: if set to true, the tool will rank the suggestions, based on importance. Default is false.
- `summarize`: if set to true, the tool will display the suggestions in a single comment. Default is false.
- `enable_help_text`: if set to true, the tool will display a help text in the comment. Default is true.
### params for '/improve --extended' mode
- `auto_extended_mode`: enable extended mode automatically (no need for the `--extended` option). Default is true. Note that a single comment has a significantly smaller PR footprint. We recommend this mode for most cases.
- `num_code_suggestions_per_chunk`: number of code suggestions provided by the 'improve' tool, per chunk. Default is 8. Also note that collapsible are not supported in _Bitbucket_. Hence, the suggestions are presented there as code comments.
- `rank_extended_suggestions`: if set to true, the tool will rank the suggestions, based on importance. Default is true.
- `max_number_of_calls`: maximum number of chunks. Default is 5.
- `final_clip_factor`: factor to remove suggestions with low confidence. Default is 0.9.
### Automatic triggering
To run the `improve` automatically when a PR is opened, define in a [configuration file](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/#wiki-configuration-file):
```
[github_app]
pr_commands = [
"/improve",
...
]
[pr_code_suggestions]
num_code_suggestions_per_chunk = ...
...
```
- The `pr_commands` lists commands that will be executed automatically when a PR is opened.
- The `[pr_code_suggestions]` section contains the configurations for the `improve` tool you want to edit (if any)
### Extended mode
An extended mode, which does not involve PR Compression and provides more comprehensive suggestions, can be invoked by commenting on any PR by setting:
```
[pr_code_suggestions]
auto_extended_mode=true
```
(This mode is true by default).
Note that the extended mode divides the PR code changes into chunks, up to the token limits, where each chunk is handled separately (might use multiple calls to GPT-4 for large PRs).
Hence, the total number of suggestions is proportional to the number of chunks, i.e., the size of the PR.
## Configuration options
!!! example "General options"
<table>
<tr>
<td><b>num_code_suggestions</b></td>
<td>Number of code suggestions provided by the 'improve' tool. Default is 4 for CLI, 0 for auto tools.</td>
</tr>
<tr>
<td><b>extra_instructions</b></td>
<td>Optional extra instructions to the tool. For example: "focus on the changes in the file X. Ignore change in ...".</td>
</tr>
<tr>
<td><b>rank_suggestions</b></td>
<td>If set to true, the tool will rank the suggestions, based on importance. Default is false.</td>
</tr>
<tr>
<td><b>commitable_code_suggestions</b></td>
<td>If set to true, the tool will display the suggestions as commitable code comments. Default is false.</td>
</tr>
<tr>
<td><b>persistent_comment</b></td>
<td>If set to true, the improve comment will be persistent, meaning that every new improve request will edit the previous one. Default is false.</td>
</tr>
<tr>
<td><b>self_reflect_on_suggestions</b></td>
<td>If set to true, the improve tool will calculate an importance score for each suggestion [1-10], and sort the suggestion labels group based on this score. Default is true.</td>
</tr>
<tr>
<td><b>suggestions_score_threshold</b></td>
<td> Any suggestion with importance score less than this threshold will be removed. Default is 0. Highly recommend not to set this value above 7-8, since above it may clip relevant suggestions that can be useful. </td>
</tr>
<tr>
<td><b>enable_help_text</b></td>
<td>If set to true, the tool will display a help text in the comment. Default is true.</td>
</tr>
</table>
!!! example "params for 'extended' mode"
<table>
<tr>
<td><b>auto_extended_mode</b></td>
<td>Enable extended mode automatically (no need for the --extended option). Default is true.</td>
</tr>
<tr>
<td><b>num_code_suggestions_per_chunk</b></td>
<td>Number of code suggestions provided by the 'improve' tool, per chunk. Default is 5.</td>
</tr>
<tr>
<td><b>rank_extended_suggestions</b></td>
<td>If set to true, the tool will rank the suggestions, based on importance. Default is true.</td>
</tr>
<tr>
<td><b>max_number_of_calls</b></td>
<td>Maximum number of chunks. Default is 5.</td>
</tr>
<tr>
<td><b>final_clip_factor</b></td>
<td>Factor to remove suggestions with low confidence. Default is 0.9.</td>
</tr>
</table>
## Usage Tips ## Usage Tips
### Extra instructions !!! tip "Extra instructions"
Extra instructions are very important for the `imrpove` tool, since they enable you to guide the model to suggestions that are more relevant to the specific needs of the project. Extra instructions are very important for the `imrpove` tool, since they enable you to guide the model to suggestions that are more relevant to the specific needs of the project.
Be specific, clear, and concise in the instructions. With extra instructions, you are the prompter. Specify relevant aspects that you want the model to focus on.
Examples for extra instructions:
```
[pr_code_suggestions] # /improve #
extra_instructions="""\
Emphasize the following aspects:
- Does the code logic cover relevant edge cases?
- Is the code logic clear and easy to understand?
- Is the code logic efficient?
...
"""
```
Use triple quotes to write multi-line instructions. Use bullet points to make the instructions more readable.
Be specific, clear, and concise in the instructions. With extra instructions, you are the prompter. Specify relevant aspects that you want the model to focus on. !!! tip "Review vs. Improve tools comparison"
Examples for extra instructions: - The [review](https://pr-agent-docs.codium.ai/tools/review/) tool includes a section called 'Possible issues', that also provide feedback on the PR Code.
``` In this section, the model is instructed to focus **only** on [major bugs and issues](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/pr_reviewer_prompts.toml#L71).
[pr_code_suggestions] # /improve # - The `improve` tool, on the other hand, has a broader mandate, and in addition to bugs and issues, it can also give suggestions for improving code quality and making the code more efficient, readable, and maintainable (see [here](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/pr_code_suggestions_prompts.toml#L34)).
extra_instructions=""" - Hence, if you are interested only in feedback about clear bugs, the `review` tool might suffice. If you want a more detailed feedback, including broader suggestions for improving the PR code, also enable the `improve` tool to run on each PR.
Emphasize the following aspects:
- Does the code logic cover relevant edge cases?
- Is the code logic clear and easy to understand?
- Is the code logic efficient?
...
"""
```
Use triple quotes to write multi-line instructions. Use bullet points to make the instructions more readable.
### A note on code suggestions quality ## A note on code suggestions quality
- While the current AI for code is getting better and better (GPT-4), it's not flawless. Not all the suggestions will be perfect, and a user should not accept all of them automatically. - While the current AI for code is getting better and better (GPT-4), it's not flawless. Not all the suggestions will be perfect, and a user should not accept all of them automatically. Critical reading and judgment are required.
- Suggestions are not meant to be [simplistic](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/pr_code_suggestions_prompts.toml#L34). Instead, they aim to give deep feedback and raise questions, ideas and thoughts to the user, who can then use his judgment, experience, and understanding of the code base. - While mistakes of the AI are rare but can happen, a real benefit from the suggestions of the `improve` (and [`review`](https://pr-agent-docs.codium.ai/tools/review/)) tool is to catch, with high probability, **mistakes or bugs done by the PR author**, when they happen. So, it's a good practice to spend the needed ~30-60 seconds to review the suggestions, even if not all of them are always relevant.
- Recommended to use the `exra_instructions` field to guide the model to suggestions that are more relevant to the specific needs of the project. - The hierarchical structure of the suggestions is designed to help the user to _quickly_ understand them, and to decide which ones are relevant and which are not:
- Consider also trying the [Custom Suggestions Tool](./custom_suggestions.md) 💎, that will **only** propose suggestions that follow specific guidelines defined by user.
- Only if the `Category` header is relevant, the user should move to the summarized suggestion description
- Only if the summarized suggestion description is relevant, the user should click on the collapsible, to read the full suggestion description with a code preview example.
In addition, we recommend to use the `exra_instructions` field to guide the model to suggestions that are more relevant to the specific needs of the project.
<br>
Consider also trying the [Custom Prompt Tool](./custom_prompt.md) 💎, that will **only** propose code suggestions that follow specific guidelines defined by user.

View File

@ -0,0 +1,29 @@
## Overview
The `improve_component` tool generates code suggestions for a specific code component that changed in the PR.
it can be invoked manually by commenting on any PR:
```
/improve_component component_name
```
To get a list of the components that changed in the PR and choose the relevant component interactively, use the [`analyze`](./analyze.md) tool.
## Example usage
Invoke the tool manually by commenting `/improve_component` on any PR:
![improve_component1](https://codium.ai/images/pr_agent/improve_component1.png){width=768}
The tool will generate code suggestions for the selected component (if no component is stated, it will generate code suggestions for the largest component):
![improve_component2](https://codium.ai/images/pr_agent/improve_component2.png){width=768}
**Notes**
- Language that are currently supported by the tool: Python, Java, C++, JavaScript, TypeScript, C#.
- This tool can also be triggered interactively by using the [`analyze`](./analyze.md) tool.
## Configuration options
- `num_code_suggestions`: number of code suggestions to provide. Default is 4
- `extra_instructions`: Optional extra instructions to the tool. For example: "focus on ...".
- `file`: in case there are several components with the same name, you can specify the relevant file.
- `class_name`: in case there are several methods with the same name in the same file, you can specify the relevant class name.

View File

@ -2,19 +2,21 @@
Here is a list of PR-Agent tools, each with a dedicated page that explains how to use it: Here is a list of PR-Agent tools, each with a dedicated page that explains how to use it:
| Tool | Description | | Tool | Description |
|-------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------| |------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| **[PR Description (`/describe`](./describe.md))** | Automatically generating PR description - title, type, summary, code walkthrough and labels | | **[PR Description (`/describe`](./describe.md))** | Automatically generating PR description - title, type, summary, code walkthrough and labels |
| **[PR Review (`/review`](./review.md))** | Adjustable feedback about the PR, possible issues, security concerns, review effort and more | | **[PR Review (`/review`](./review.md))** | Adjustable feedback about the PR, possible issues, security concerns, review effort and more |
| **[Code Suggestions (`/improve`](./improve.md))** | Code suggestions for improving the PR | | **[Code Suggestions (`/improve`](./improve.md))** | Code suggestions for improving the PR |
| **[Question Answering (`/ask ...`](./ask.md))** | Answering free-text questions about the PR, or on specific code lines | | **[Question Answering (`/ask ...`](./ask.md))** | Answering free-text questions about the PR, or on specific code lines |
| **[Update Changelog (`/update_changelog`](./update_changelog.md))** | Automatically updating the CHANGELOG.md file with the PR changes | | **[Update Changelog (`/update_changelog`](./update_changelog.md))** | Automatically updating the CHANGELOG.md file with the PR changes |
| **[Find Similar Issue (`/similar_issue`](./similar_issues.md))** | Automatically retrieves and presents similar issues | | **[Find Similar Issue (`/similar_issue`](./similar_issues.md))** | Automatically retrieves and presents similar issues |
| **💎 [Add Documentation (`/add_docs`](./documentation.md))** | Generates documentation to methods/functions/classes that changed in the PR | | **[Help (`/help`](./help.md))** | Provides a list of all the available tools. Also enables to trigger them interactively (💎) |
| **💎 [Generate Custom Labels (`/generate_labels`](./custom_labels.md))** | Generates custom labels for the PR, based on specific guidelines defined by the user | | **💎 [Add Documentation (`/add_docs`](./documentation.md))** | Generates documentation to methods/functions/classes that changed in the PR |
| **💎 [Analyze (`/analyze`](./analyze.md))** | Identify code components that changed in the PR, and enables to interactively generate tests, docs, and code suggestions for each component | | **💎 [Generate Custom Labels (`/generate_labels`](./custom_labels.md))** | Generates custom labels for the PR, based on specific guidelines defined by the user |
| **💎 [Custom Suggestions (`/custom_suggestions`](./custom_suggestions.md))** | Automatically generates custom suggestions for improving the PR code, based on specific guidelines defined by the user | | **💎 [Analyze (`/analyze`](./analyze.md))** | Identify code components that changed in the PR, and enables to interactively generate tests, docs, and code suggestions for each component |
| **💎 [Generate Tests (`/test component_name`](./test.md))** | Automatically generates unit tests for a selected component, based on the PR code changes | | **💎 [Custom Prompt (`/custom_prompt`](./custom_prompt.md))** | Automatically generates custom suggestions for improving the PR code, based on specific guidelines defined by the user |
| **💎 [CI Feedback (`/checks ci_job`](./ci_feedback.md))** | Automatically generates feedback and analysis for a failed CI job | | **💎 [Generate Tests (`/test component_name`](./test.md))** | Automatically generates unit tests for a selected component, based on the PR code changes |
| **💎 [Improve Component (`/improve_component component_name`](./improve_component.md))** | Generates code suggestions for a specific code component that changed in the PR |
| **💎 [CI Feedback (`/checks ci_job`](./ci_feedback.md))** | Automatically generates feedback and analysis for a failed CI job |
Note that the tools marked with 💎 are available only for PR-Agent Pro users. Note that the tools marked with 💎 are available only for PR-Agent Pro users.

View File

@ -4,48 +4,43 @@ The tool can be triggered automatically every time a new PR is [opened](../usage
``` ```
/review /review
``` ```
For example:
<kbd><img src=https://codium.ai/images/pr_agent/review_comment.png width="768"></kbd> ## Example usage
<kbd><img src=https://codium.ai/images/pr_agent/review.png width="768"></kbd> ### Manual triggering
Invoke the tool manually by commenting `/review` on any PR:
## Configuration options ![review comment](https://codium.ai/images/pr_agent/review_comment.png){width=512}
To edit [configurations](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L19) related to the review tool (`pr_reviewer` section), use the following template: After ~30 seconds, the tool will generate a review for the PR:
![review](https://codium.ai/images/pr_agent/review3.png){width=512}
If you want to edit [configurations](#configuration-options), add the relevant ones to the command:
``` ```
/review --pr_reviewer.some_config1=... --pr_reviewer.some_config2=... /review --pr_reviewer.some_config1=... --pr_reviewer.some_config2=...
``` ```
#### General options ### Automatic triggering
- `num_code_suggestions`: number of code suggestions provided by the 'review' tool. For manual comments, default is 4. For [PR-Agent app](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L142) auto tools, default is 0, meaning no code suggestions will be provided by the review tool, unless you manually edit `pr_commands`.
- `inline_code_comments`: if set to true, the tool will publish the code suggestions as comments on the code diff. Default is false.
- `persistent_comment`: if set to true, the review comment will be persistent, meaning that every new review request will edit the previous one. Default is true.
- `extra_instructions`: Optional extra instructions to the tool. For example: "focus on the changes in the file X. Ignore change in ...".
#### Enable\\disable features To run the `review` automatically when a PR is opened, define in a [configuration file](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/#wiki-configuration-file):
- `require_focused_review`: if set to true, the tool will add a section - 'is the PR a focused one'. Default is false. ```
- `require_score_review`: if set to true, the tool will add a section that scores the PR. Default is false. [github_app]
- `require_tests_review`: if set to true, the tool will add a section that checks if the PR contains tests. Default is true. pr_commands = [
- `require_estimate_effort_to_review`: if set to true, the tool will add a section that estimates the effort needed to review the PR. Default is true. "/review",
...
]
#### SOC2 ticket compliance 💎 [pr_reviewer]
> This feature is available only in PR-Agent Pro num_code_suggestions = ...
...
```
This sub-tool checks if the PR description properly contains a ticket to a project management system (e.g., Jira, Asana, Trello, etc.), as required by SOC2 compliance. If not, it will add a label to the PR: "Missing SOC2 ticket". - The `pr_commands` lists commands that will be executed automatically when a PR is opened.
- `require_soc2_ticket`: If set to true, the SOC2 ticket checker sub-tool will be enabled. Default is false. - The `[pr_reviewer]` section contains the configurations for the `review` tool you want to edit (if any).
- `soc2_ticket_prompt`: The prompt for the SOC2 ticket review. Default is: `Does the PR description include a link to ticket in a project management system (e.g., Jira, Asana, Trello, etc.) ?`. Edit this field if your compliance requirements are different.
#### Adding PR labels ### Incremental Mode
- `enable_review_labels_security`: if set to true, the tool will publish a 'possible security issue' label if it detects a security issue. Default is true.
- `enable_review_labels_effort`: if set to true, the tool will publish a 'Review effort [1-5]: x' label. Default is true.
#### Auto-approval
- `enable_auto_approval`: if set to true, the tool will approve the PR when invoked with the 'auto_approve' command. Default is false. This flag can be changed only from configuration file.
- `maximal_review_effort`: maximal effort level for auto-approval. If the PR's estimated review effort is above this threshold, the auto-approval will not run. Default is 5.
#### Incremental Mode
Incremental review only considers changes since the last PR-Agent review. This can be useful when working on the PR in an iterative manner, and you want to focus on the changes since the last review instead of reviewing the entire PR again. Incremental review only considers changes since the last PR-Agent review. This can be useful when working on the PR in an iterative manner, and you want to focus on the changes since the last review instead of reviewing the entire PR again.
For invoking the incremental mode, the following command can be used: For invoking the incremental mode, the following command can be used:
``` ```
@ -53,23 +48,9 @@ For invoking the incremental mode, the following command can be used:
``` ```
Note that the incremental mode is only available for GitHub. Note that the incremental mode is only available for GitHub.
<kbd><img src=https://codium.ai/images/pr_agent/incremental_review.png width="768"></kbd> ![incremental review](https://codium.ai/images/pr_agent/incremental_review_2.png){width=512}
Under the section 'pr_reviewer', the [configuration file](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L19) contains options to customize the 'review -i' tool. ### PR Reflection
These configurations can be used to control the rate at which the incremental review tool will create new review comments when invoked automatically, to prevent making too much noise in the PR.
- `minimal_commits_for_incremental_review`: Minimal number of commits since the last review that are required to create incremental review.
If there are less than the specified number of commits since the last review, the tool will not perform any action.
Default is 0 - the tool will always run, no matter how many commits since the last review.
- `minimal_minutes_for_incremental_review`: Minimal number of minutes that need to pass since the last reviewed commit to create incremental review.
If less than the specified number of minutes have passed between the last reviewed commit and running this command, the tool will not perform any action.
Default is 0 - the tool will always run, no matter how much time have passed since the last reviewed commit.
- `require_all_thresholds_for_incremental_review`: If set to true, all the previous thresholds must be met for incremental review to run. If false, only one is enough to run the tool.
For example, if `minimal_commits_for_incremental_review=2` and `minimal_minutes_for_incremental_review=2`, and we have 3 commits since the last review, but the last reviewed commit is from 1 minute ago:
When `require_all_thresholds_for_incremental_review=true` the incremental review __will not__ run, because only 1 out of 2 conditions were met (we have enough commits but the last review is too recent),
but when `require_all_thresholds_for_incremental_review=false` the incremental review __will__ run, because one condition is enough (we have 3 commits which is more than the configured 2).
Default is false - the tool will run as long as at least once conditions is met.
#### PR Reflection
By invoking: By invoking:
``` ```
@ -77,92 +58,185 @@ By invoking:
``` ```
The tool will first ask the author questions about the PR, and will guide the review based on their answers. The tool will first ask the author questions about the PR, and will guide the review based on their answers.
<kbd><img src=https://codium.ai/images/pr_agent/reflection_questions.png width="768"></kbd> ![reflection questions](https://codium.ai/images/pr_agent/reflection_questions.png){width=512}
<kbd><img src=https://codium.ai/images/pr_agent/reflection_answers.png width="768"></kbd> ![reflection answers](https://codium.ai/images/pr_agent/reflection_answers.png){width=512}
<kbd><img src=https://codium.ai/images/pr_agent/reflection_insights.png width="768"></kbd> ![reflection insights](https://codium.ai/images/pr_agent/reflection_insights.png){width=512}
## Configuration options
!!! example "General options"
<table>
<tr>
<td><b>num_code_suggestions</b></td>
<td>Number of code suggestions provided by the 'review' tool. For manual comments, default is 4. For PR-Agent app auto tools, default is 0, meaning no code suggestions will be provided by the review tool, unless you manually edit pr_commands.</td>
</tr>
<tr>
<td><b>inline_code_comments</b></td>
<td>If set to true, the tool will publish the code suggestions as comments on the code diff. Default is false.</td>
</tr>
<tr>
<td><b>persistent_comment</b></td>
<td>If set to true, the review comment will be persistent, meaning that every new review request will edit the previous one. Default is true.</td>
</tr>
<tr>
<td><b>extra_instructions</b></td>
<td>Optional extra instructions to the tool. For example: "focus on the changes in the file X. Ignore change in ...".</td>
</tr>
<tr>
<td><b>enable_help_text</b></td>
<td>If set to true, the tool will display a help text in the comment. Default is true.</td>
</tr>
</table>
!!! example "Enable\\disable specific sub-sections"
<table>
<tr>
<td><b>require_score_review</b></td>
<td>If set to true, the tool will add a section that scores the PR. Default is false.</td>
</tr>
<tr>
<td><b>require_tests_review</b></td>
<td>If set to true, the tool will add a section that checks if the PR contains tests. Default is true.</td>
</tr>
<tr>
<td><b>require_estimate_effort_to_review</b></td>
<td>If set to true, the tool will add a section that estimates the effort needed to review the PR. Default is true.</td>
</tr>
<tr>
<td><b>require_can_be_split_review</b></td>
<td>If set to true, the tool will add a section that checks if the PR contains several themes, and can be split into smaller PRs. Default is false.</td>
</tr>
</table>
!!! example "SOC2 ticket compliance 💎"
This sub-tool checks if the PR description properly contains a ticket to a project management system (e.g., Jira, Asana, Trello, etc.), as required by SOC2 compliance. If not, it will add a label to the PR: "Missing SOC2 ticket".
<table>
<tr>
<td><b>require_soc2_ticket</b></td>
<td>If set to true, the SOC2 ticket checker sub-tool will be enabled. Default is false.</td>
</tr>
<tr>
<td><b>soc2_ticket_prompt</b></td>
<td>The prompt for the SOC2 ticket review. Default is: `Does the PR description include a link to ticket in a project management system (e.g., Jira, Asana, Trello, etc.) ?`. Edit this field if your compliance requirements are different.</td>
</tr>
</table>
!!! example "Adding PR labels"
You can enable\disable the `review` tool to add specific labels to the PR:
<table>
<tr>
<td><b>enable_review_labels_security</b></td>
<td>If set to true, the tool will publish a 'possible security issue' label if it detects a security issue. Default is true.</td>
</tr>
<tr>
<td><b>enable_review_labels_effort</b></td>
<td>If set to true, the tool will publish a 'Review effort [1-5]: x' label. Default is true.</td>
</tr>
</table>
!!! example "Auto-approval"
If enabled, the `review` tool can approve a PR when a specific comment, `/review auto_approve`, is invoked.
<table>
<tr>
<td><b>enable_auto_approval</b></td>
<td>If set to true, the tool will approve the PR when invoked with the 'auto_approve' command. Default is false. This flag can be changed only from configuration file.</td>
</tr>
<tr>
<td><b>maximal_review_effort</b></td>
<td>Maximal effort level for auto-approval. If the PR's estimated review effort is above this threshold, the auto-approval will not run. Default is 5.</td>
</tr>
</table>
## Usage Tips ## Usage Tips
### General guidelines !!! tip "General guidelines"
The `review` tool provides a collection of possible feedbacks about a PR. The `review` tool provides a collection of possible feedbacks about a PR.
It is recommended to review the [Configuration options](#configuration-options) section, and choose the relevant options for your use case. It is recommended to review the [Configuration options](#configuration-options) section, and choose the relevant options for your use case.
Some of the features that are disabled by default are quite useful, and should be considered for enabling. For example:
`require_score_review`, `require_soc2_ticket`, and more.
On the other hand, if you find one of the enabled features to be irrelevant for your use case, disable it. No default configuration can fit all use cases.
Some of the features that are disabled by default are quite useful, and should be considered for enabling. For example: !!! tip "Automation"
`require_score_review`, `require_soc2_ticket`, and more. When you first install PR-Agent app, the [default mode](../usage-guide/automations_and_usage.md#github-app-automatic-tools-when-a-new-pr-is-opened) for the `review` tool is:
```
pr_commands = ["/review --pr_reviewer.num_code_suggestions=0", ...]
```
Meaning the `review` tool will run automatically on every PR, without providing code suggestions.
Edit this field to enable/disable the tool, or to change the used configurations.
On the other hand, if you find one of the enabled features to be irrelevant for your use case, disable it. No default configuration can fit all use cases. !!! tip "Code suggestions"
### Code suggestions If you set `num_code_suggestions`>0 , the `review` tool will also provide code suggestions.
Notice If you are interested **only** in the code suggestions, it is recommended to use the [`improve`](./improve.md) feature instead, since it is a dedicated only to code suggestions, and usually gives better results.
Use the `review` tool if you want to get more comprehensive feedback, which includes code suggestions as well.
If you set `num_code_suggestions`>0 , the `review` tool will also provide code suggestions. !!! tip "Possible labels from the review tool"
Notice If you are interested **only** in the code suggestions, it is recommended to use the [`improve`](./improve.md) feature instead, since it is a dedicated only to code suggestions, and usually gives better results. The `review` tool can auto-generate two specific types of labels for a PR:
Use the `review` tool if you want to get more comprehensive feedback, which includes code suggestions as well.
- a `possible security issue` label that detects if a possible [security issue](https://github.com/Codium-ai/pr-agent/blob/tr/user_description/pr_agent/settings/pr_reviewer_prompts.toml#L136) exists in the PR code (`enable_review_labels_security` flag)
- a `Review effort [1-5]: x` label, where x is the estimated effort to review the PR (`enable_review_labels_effort` flag)
Both modes are useful, and we recommended to enable them.
### Automation !!! tip "Extra instructions"
- When you first install the app, the [default mode](../usage-guide/automations_and_usage.md#github-app-automatic-tools-when-a-new-pr-is-opened) for the `review` tool is:
```
pr_commands = ["/review", ...]
```
Meaning the `review` tool will run automatically on every PR, with the default configuration.
Edit this field to enable/disable the tool, or to change the used configurations.
### Auto-labels Extra instructions are important.
The `review` tool can be configured with extra instructions, which can be used to guide the model to a feedback tailored to the needs of your project.
The `review` tool can auto-generate two specific types of labels for a PR:
Be specific, clear, and concise in the instructions. With extra instructions, you are the prompter. Specify the relevant sub-tool, and the relevant aspects of the PR that you want to emphasize.
- a `possible security issue` label that detects a possible [security issue](https://github.com/Codium-ai/pr-agent/blob/tr/user_description/pr_agent/settings/pr_reviewer_prompts.toml#L136) (`enable_review_labels_security` flag)
- a `Review effort [1-5]: x` label, where x is the estimated effort to review the PR (`enable_review_labels_effort` flag) Examples for extra instructions:
```
Both modes are useful, and we recommended to enable them. [pr_reviewer]
extra_instructions="""\
### Extra instructions In the code feedback section, emphasize the following:
- Does the code logic cover relevant edge cases?
Extra instructions are important. - Is the code logic clear and easy to understand?
The `review` tool can be configured with extra instructions, which can be used to guide the model to a feedback tailored to the needs of your project. - Is the code logic efficient?
...
Be specific, clear, and concise in the instructions. With extra instructions, you are the prompter. Specify the relevant sub-tool, and the relevant aspects of the PR that you want to emphasize. """
```
Examples for extra instructions: Use triple quotes to write multi-line instructions. Use bullet points to make the instructions more readable.
```
[pr_reviewer] # /review #
extra_instructions="""
In the code feedback section, emphasize the following:
- Does the code logic cover relevant edge cases?
- Is the code logic clear and easy to understand?
- Is the code logic efficient?
...
"""
```
Use triple quotes to write multi-line instructions. Use bullet points to make the instructions more readable.
### Auto-approval !!! tip "Auto-approval"
PR-Agent can approve a PR when a specific comment is invoked. PR-Agent can approve a PR when a specific comment is invoked.
To ensure safety, the auto-approval feature is disabled by default. To enable auto-approval, you need to actively set in a pre-defined configuration file the following: To ensure safety, the auto-approval feature is disabled by default. To enable auto-approval, you need to actively set in a pre-defined configuration file the following:
``` ```
[pr_reviewer] [pr_reviewer]
enable_auto_approval = true enable_auto_approval = true
``` ```
(this specific flag cannot be set with a command line argument, only in the configuration file, committed to the repository) (this specific flag cannot be set with a command line argument, only in the configuration file, committed to the repository)
After enabling, by commenting on a PR: After enabling, by commenting on a PR:
``` ```
/review auto_approve /review auto_approve
``` ```
PR-Agent will automatically approve the PR, and add a comment with the approval. PR-Agent will automatically approve the PR, and add a comment with the approval.
You can also enable auto-approval only if the PR meets certain requirements, such as that the `estimated_review_effort` label is equal or below a certain threshold, by adjusting the flag: You can also enable auto-approval only if the PR meets certain requirements, such as that the `estimated_review_effort` label is equal or below a certain threshold, by adjusting the flag:
``` ```
[pr_reviewer] [pr_reviewer]
maximal_review_effort = 5 maximal_review_effort = 5
``` ```

View File

@ -5,7 +5,8 @@ For example:
`Global Search` for a method called `chat_completion`: `Global Search` for a method called `chat_completion`:
<kbd><img src=https://codium.ai/images/pr_agent/similar_code_global2.png width="768"></kbd> ![similar code global](https://codium.ai/images/pr_agent/similar_code_global2.png){width=768}
PR-Agent will examine the code component and will extract the most relevant keywords to search for similar code: PR-Agent will examine the code component and will extract the most relevant keywords to search for similar code:
@ -16,11 +17,12 @@ PR-Agent will examine the code component and will extract the most relevant keyw
Search result link example: Search result link example:
<kbd><img src=https://codium.ai/images/pr_agent/code_search_result_single.png width="768"></kbd> ![code search result single](https://codium.ai/images/pr_agent/code_search_result_single.png){width=768}
`Organization Search`: `Organization Search`:
<kbd><img src=https://codium.ai/images/pr_agent/similar_code_org.png width="768"></kbd> ![similar code org](https://codium.ai/images/pr_agent/similar_code_org.png){width=768}
## How to use ## How to use
@ -47,11 +49,11 @@ It can be invoked automatically from the analyze table, can be accessed by:
/analyze /analyze
``` ```
Choose the components you want to find similar code for, and click on the `similar` checkbox. Choose the components you want to find similar code for, and click on the `similar` checkbox.
<kbd><img src=https://codium.ai/images/pr_agent/analyze_similar.png width="768"></kbd> ![analyze similar](https://codium.ai/images/pr_agent/analyze_similar.png){width=768}
If you are looking to search for similar code in the organization's codebase, you can click on the `Organization` checkbox, and it will invoke a new search command just for the organization's codebase. If you are looking to search for similar code in the organization's codebase, you can click on the `Organization` checkbox, and it will invoke a new search command just for the organization's codebase.
<kbd><img src=https://codium.ai/images/pr_agent/similar_code_global.png width="768"></kbd> ![similar code global](https://codium.ai/images/pr_agent/similar_code_global.png){width=768}
## Configuration options ## Configuration options

View File

@ -4,13 +4,15 @@ It can be invoked manually by commenting on any PR:
``` ```
/similar_issue /similar_issue
``` ```
For example:
<kbd><img src=https://codium.ai/images/pr_agent/similar_issue_original_issue.png width="768"></kbd>
<kbd><img src=https://codium.ai/images/pr_agent/similar_issue_comment.png width="768"></kbd> ## Example usage
<kbd><img src=https://codium.ai/images/pr_agent/similar_issue.png width="768"></kbd> ![similar_issue_original_issue](https://codium.ai/images/pr_agent/similar_issue_original_issue.png){width=768}
![similar_issue_comment](https://codium.ai/images/pr_agent/similar_issue_comment.png){width=768}
![similar_issue](https://codium.ai/images/pr_agent/similar_issue.png){width=768}
Note that to perform retrieval, the `similar_issue` tool indexes all the repo previous issues (once). Note that to perform retrieval, the `similar_issue` tool indexes all the repo previous issues (once).

View File

@ -5,19 +5,25 @@ It can be invoked manually by commenting on any PR:
/test component_name /test component_name
``` ```
where 'component_name' is the name of a specific component in the PR. where 'component_name' is the name of a specific component in the PR.
To get a list of the components that changed in the PR, use the [`analyze`](./analyze.md) tool. To get a list of the components that changed in the PR and choose the relevant component interactively, use the [`analyze`](./analyze.md) tool.
## Example usage
An example [result](https://github.com/Codium-ai/pr-agent/pull/598#issuecomment-1913679429): Invoke the tool manually by commenting `/test` on any PR:
<kbd><img src=https://codium.ai/images/pr_agent/test1.png width="704"></kbd> ![test1](https://codium.ai/images/pr_agent/test1.png){width=704}
<kbd><img src=https://codium.ai/images/pr_agent/test2.png width="768"></kbd> The tool will generate tests for the selected component (if no component is stated, it will generate tests for largest component):
<kbd><img src=https://codium.ai/images/pr_agent/test3.png width="768"></kbd> ![test2](https://codium.ai/images/pr_agent/test2.png){width=768}
![test3](https://codium.ai/images/pr_agent/test3.png){width=768}
(Example taken from [here](https://github.com/Codium-ai/pr-agent/pull/598#issuecomment-1913679429)):
**Notes** **Notes**
- Language that are currently supported by the tool: Python, Java, C++, JavaScript, TypeScript. - Language that are currently supported by the tool: Python, Java, C++, JavaScript, TypeScript, C#.
- This tool can also be triggered interactively by using the [`analyze`](./analyze.md) tool.
## Configuration options ## Configuration options

View File

@ -4,16 +4,16 @@ It can be invoked manually by commenting on any PR:
``` ```
/update_changelog /update_changelog
``` ```
For example:
<kbd><img src=https://codium.ai/images/pr_agent/update_changelog_comment.png width="768"></kbd> ## Example usage
<kbd><img src=https://codium.ai/images/pr_agent/update_changelog.png width="768"></kbd> ![update_changelog_comment](https://codium.ai/images/pr_agent/update_changelog_comment.png){width=768}
![update_changelog](https://codium.ai/images/pr_agent/update_changelog.png){width=768}
## Configuration options ## Configuration options
Under the section 'pr_update_changelog', the [configuration file](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L50) contains options to customize the 'update changelog' tool: Under the section `pr_update_changelog`, the [configuration file](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L50) contains options to customize the 'update changelog' tool:
- `push_changelog_changes`: whether to push the changes to CHANGELOG.md, or just print them. Default is false (print only). - `push_changelog_changes`: whether to push the changes to CHANGELOG.md, or just print them. Default is false (print only).
- `extra_instructions`: Optional extra instructions to the tool. For example: "focus on the changes in the file X. Ignore change in ... - `extra_instructions`: Optional extra instructions to the tool. For example: "focus on the changes in the file X. Ignore change in ...

View File

@ -7,10 +7,10 @@ To ignore files or directories, edit the **[ignore.toml](https://github.com/Codi
- `IGNORE.GLOB` - `IGNORE.GLOB`
- `IGNORE.REGEX` - `IGNORE.REGEX`
For example, to ignore python files in a PR with online usage, comment on a PR: For example, to ignore Python files in a PR with online usage, comment on a PR:
`/review --ignore.glob=['*.py']` `/review --ignore.glob=['*.py']`
To ignore python files in all PRs, set in a configuration file: To ignore Python files in all PRs, set in a configuration file:
``` ```
[ignore] [ignore]
glob = ['*.py'] glob = ['*.py']
@ -26,13 +26,13 @@ All PR-Agent tools have a parameter called `extra_instructions`, that enables to
## Working with large PRs ## Working with large PRs
The default mode of CodiumAI is to have a single call per tool, using GPT-4, which has a token limit of 8000 tokens. The default mode of CodiumAI is to have a single call per tool, using GPT-4, which has a token limit of 8000 tokens.
This mode provide a very good speed-quality-cost tradeoff, and can handle most PRs successfully. This mode provides a very good speed-quality-cost tradeoff, and can handle most PRs successfully.
When the PR is above the token limit, it employs a [PR Compression strategy](../core-abilities/index.md). When the PR is above the token limit, it employs a [PR Compression strategy](../core-abilities/index.md).
However, for very large PRs, or in case you want to emphasize quality over speed and cost, there are 2 possible solutions: However, for very large PRs, or in case you want to emphasize quality over speed and cost, there are two possible solutions:
1) [Use a model](https://codium-ai.github.io/Docs-PR-Agent/usage-guide/#changing-a-model) with larger context, like GPT-32K, or claude-100K. This solution will be applicable for all the tools. 1) [Use a model](https://codium-ai.github.io/Docs-PR-Agent/usage-guide/#changing-a-model) with larger context, like GPT-32K, or claude-100K. This solution will be applicable for all the tools.
2) For the `/improve` tool, there is an ['extended' mode](https://codium-ai.github.io/Docs-PR-Agent/tools/#improve) (`/improve --extended`), 2) For the `/improve` tool, there is an ['extended' mode](https://codium-ai.github.io/Docs-PR-Agent/tools/#improve) (`/improve --extended`),
which divides the PR to chunks, and process each chunk separately. With this mode, regardless of the model, no compression will be done (but for large PRs, multiple model calls may occur) which divides the PR to chunks, and processes each chunk separately. With this mode, regardless of the model, no compression will be done (but for large PRs, multiple model calls may occur)
## Changing a model ## Changing a model
@ -79,6 +79,7 @@ MAX_TOKENS={
[config] # in configuration.toml [config] # in configuration.toml
model = "ollama/llama2" model = "ollama/llama2"
model_turbo = "ollama/llama2"
[ollama] # in .secrets.toml [ollama] # in .secrets.toml
api_base = ... # the base url for your huggingface inference endpoint api_base = ... # the base url for your huggingface inference endpoint
@ -101,6 +102,7 @@ MAX_TOKENS={
} }
[config] # in configuration.toml [config] # in configuration.toml
model = "huggingface/meta-llama/Llama-2-7b-chat-hf" model = "huggingface/meta-llama/Llama-2-7b-chat-hf"
model_turbo = "huggingface/meta-llama/Llama-2-7b-chat-hf"
[huggingface] # in .secrets.toml [huggingface] # in .secrets.toml
key = ... # your huggingface api key key = ... # your huggingface api key
@ -114,13 +116,27 @@ To use Llama2 model with Replicate, for example, set:
``` ```
[config] # in configuration.toml [config] # in configuration.toml
model = "replicate/llama-2-70b-chat:2c1608e18606fad2812020dc541930f2d0495ce32eee50074220b87300bc16e1" model = "replicate/llama-2-70b-chat:2c1608e18606fad2812020dc541930f2d0495ce32eee50074220b87300bc16e1"
model_turbo = "replicate/llama-2-70b-chat:2c1608e18606fad2812020dc541930f2d0495ce32eee50074220b87300bc16e1"
[replicate] # in .secrets.toml [replicate] # in .secrets.toml
key = ... key = ...
``` ```
(you can obtain a Llama2 key from [here](https://replicate.com/replicate/llama-2-70b-chat/api)) (you can obtain a Llama2 key from [here](https://replicate.com/replicate/llama-2-70b-chat/api))
Also review the [AiHandler](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/algo/ai_handler.py) file for instruction how to set keys for other models. Also, review the [AiHandler](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/algo/ai_handler.py) file for instructions on how to set keys for other models.
### Groq
To use Llama3 model with Groq, for example, set:
```
[config] # in configuration.toml
model = "llama3-70b-8192"
model_turbo = "llama3-70b-8192"
fallback_models = ["groq/llama3-70b-8192"]
[groq] # in .secrets.toml
key = ... # your Groq api key
```
(you can obtain a Groq key from [here](https://console.groq.com/keys))
### Vertex AI ### Vertex AI
@ -129,6 +145,7 @@ To use Google's Vertex AI platform and its associated models (chat-bison/codecha
``` ```
[config] # in configuration.toml [config] # in configuration.toml
model = "vertex_ai/codechat-bison" model = "vertex_ai/codechat-bison"
model_turbo = "vertex_ai/codechat-bison"
fallback_models="vertex_ai/codechat-bison" fallback_models="vertex_ai/codechat-bison"
[vertexai] # in .secrets.toml [vertexai] # in .secrets.toml
@ -162,8 +179,9 @@ To use Amazon Bedrock and its foundational models, add the below configuration:
``` ```
[config] # in configuration.toml [config] # in configuration.toml
model = "anthropic.claude-v2" model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"
fallback_models="anthropic.claude-instant-v1" model_turbo="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"
fallback_models=["bedrock/anthropic.claude-v2:1"]
[aws] # in .secrets.toml [aws] # in .secrets.toml
bedrock_region = "us-east-1" bedrock_region = "us-east-1"
@ -171,12 +189,18 @@ bedrock_region = "us-east-1"
Note that you have to add access to foundational models before using them. Please refer to [this document](https://docs.aws.amazon.com/bedrock/latest/userguide/setting-up.html) for more details. Note that you have to add access to foundational models before using them. Please refer to [this document](https://docs.aws.amazon.com/bedrock/latest/userguide/setting-up.html) for more details.
If you are using the claude-3 model, please configure the following settings as there are parameters incompatible with claude-3.
```
[litellm]
drop_params = true
```
AWS session is automatically authenticated from your environment, but you can also explicitly set `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables. AWS session is automatically authenticated from your environment, but you can also explicitly set `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables.
## Patch Extra Lines ## Patch Extra Lines
By default, around any change in your PR, git patch provides 3 lines of context above and below the change. By default, around any change in your PR, git patch provides three lines of context above and below the change.
``` ```
@@ -12,5 +12,5 @@ def func1(): @@ -12,5 +12,5 @@ def func1():
code line that already existed in the file... code line that already existed in the file...

View File

@ -1,5 +1,5 @@
## Local repo (CLI) ## Local repo (CLI)
When running from your local repo (CLI), your local configuration file will be used. When running from your locally cloned PR-Agent repo (CLI), your local configuration file will be used.
Examples of invoking the different tools via the CLI: Examples of invoking the different tools via the CLI:
- **Review**: `python -m pr_agent.cli --pr_url=<pr_url> review` - **Review**: `python -m pr_agent.cli --pr_url=<pr_url> review`
@ -50,6 +50,10 @@ Any configuration value in [configuration file](https://github.com/Codium-ai/pr-
## GitHub App ## GitHub App
!!! note "Configurations for PR-Agent Pro"
PR-Agent Pro for GitHub is an App, hosted by CodiumAI. So all the instructions below are relevant also for PR-Agent Pro users.
Same goes for [GitLab webhook](#gitlab-webhook) and [BitBucket App](#bitbucket-app) sections.
### GitHub app automatic tools when a new PR is opened ### GitHub app automatic tools when a new PR is opened
The [github_app](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L108) section defines GitHub app specific configurations. The [github_app](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L108) section defines GitHub app specific configurations.
@ -58,22 +62,21 @@ The configuration parameter `pr_commands` defines the list of tools that will be
``` ```
[github_app] [github_app]
pr_commands = [ pr_commands = [
"/describe --pr_description.add_original_user_description=true --pr_description.keep_original_user_title=true --pr_description.final_update_message=false", "/describe --pr_description.final_update_message=false",
"/review --pr_reviewer.num_code_suggestions=0 --pr_reviewer.final_update_message=false", "/review --pr_reviewer.num_code_suggestions=0",
"/improve", "/improve",
] ]
``` ```
This means that when a new PR is opened/reopened or marked as ready for review, PR-Agent will run the `describe`, `review` and `improve` tools. This means that when a new PR is opened/reopened or marked as ready for review, PR-Agent will run the `describe`, `review` and `improve` tools.
For the `describe` tool, for example, the `add_original_user_description` and `keep_original_user_title` parameters will be set to true. For the `review` tool, for example, the `num_code_suggestions` parameter will be set to 0.
You can override the default tool parameters by using one the three options for a [configuration file](https://codium-ai.github.io/Docs-PR-Agent/usage-guide/#configuration-options): **wiki**, **local**, or **global**. You can override the default tool parameters by using one the three options for a [configuration file](https://codium-ai.github.io/Docs-PR-Agent/usage-guide/#configuration-options): **wiki**, **local**, or **global**.
For example, if your local `.pr_agent.toml` file contains: For example, if your local `.pr_agent.toml` file contains:
``` ```
[pr_description] [pr_description]
add_original_user_description = false generate_ai_title = true
keep_original_user_title = false
``` ```
When a new PR is opened, PR-Agent will run the `describe` tool with the above parameters. Every time you run the `describe` tool, including automatic runs, the PR title will be generated by the AI.
To cancel the automatic run of all the tools, set: To cancel the automatic run of all the tools, set:
``` ```
@ -98,14 +101,14 @@ The configuration parameter `push_commands` defines the list of tools that will
[github_app] [github_app]
handle_push_trigger = true handle_push_trigger = true
push_commands = [ push_commands = [
"/describe --pr_description.add_original_user_description=true --pr_description.keep_original_user_title=true", "/describe",
"/review --pr_reviewer.num_code_suggestions=0", "/review --pr_reviewer.num_code_suggestions=0 --pr_reviewer.final_update_message=false",
] ]
``` ```
This means that when new code is pushed to the PR, the PR-Agent will run the `describe` and `review` tools, with the specified parameters. This means that when new code is pushed to the PR, the PR-Agent will run the `describe` and `review` tools, with the specified parameters.
## GitHub Action ## GitHub Action
`GitHub Action` is a different way to trigger PR-Agent tools, and uses a different configuration mechanism than `GitHub App`. `GitHub Action` is a different way to trigger PR-Agent tools, and uses a different configuration mechanism than `GitHub App`.<br>
You can configure settings for `GitHub Action` by adding environment variables under the env section in `.github/workflows/pr_agent.yml` file. You can configure settings for `GitHub Action` by adding environment variables under the env section in `.github/workflows/pr_agent.yml` file.
Specifically, start by setting the following environment variables: Specifically, start by setting the following environment variables:
```yaml ```yaml
@ -115,24 +118,30 @@ Specifically, start by setting the following environment variables:
github_action_config.auto_review: "true" # enable\disable auto review github_action_config.auto_review: "true" # enable\disable auto review
github_action_config.auto_describe: "true" # enable\disable auto describe github_action_config.auto_describe: "true" # enable\disable auto describe
github_action_config.auto_improve: "true" # enable\disable auto improve github_action_config.auto_improve: "true" # enable\disable auto improve
github_action_config.enable_output: "true" # enable\disable github actions output parameter
``` ```
`github_action_config.auto_review`, `github_action_config.auto_describe` and `github_action_config.auto_improve` are used to enable/disable automatic tools that run when a new PR is opened. `github_action_config.auto_review`, `github_action_config.auto_describe` and `github_action_config.auto_improve` are used to enable/disable automatic tools that run when a new PR is opened.
If not set, the default configuration is for all three tools to run automatically when a new PR is opened. If not set, the default configuration is for all three tools to run automatically when a new PR is opened.
Note that you can give additional config parameters by adding environment variables to `.github/workflows/pr_agent.yml`, or by using a `.pr_agent.toml` file in the root of your repo, similar to the GitHub App usage. `github_action_config.enable_output` are used to enable/disable github actions [output parameter](https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#outputs-for-docker-container-and-javascript-actions) (default is `true`).
Review result is output as JSON to `steps.{step-id}.outputs.review` property.
The JSON structure is equivalent to the yaml data structure defined in [pr_reviewer_prompts.toml](https://github.com/idubnori/pr-agent/blob/main/pr_agent/settings/pr_reviewer_prompts.toml).
For example, you can set an environment variable: `pr_description.add_original_user_description=false`, or add a `.pr_agent.toml` file with the following content: Note that you can give additional config parameters by adding environment variables to `.github/workflows/pr_agent.yml`, or by using a `.pr_agent.toml` [configuration file](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/#global-configuration-file) in the root of your repo
For example, you can set an environment variable: `pr_description.publish_labels=false`, or add a `.pr_agent.toml` file with the following content:
``` ```
[pr_description] [pr_description]
add_original_user_description = false publish_labels = false
``` ```
to prevent PR-Agent from publishing labels when running the `describe` tool.
## GitLab Webhook ## GitLab Webhook
After setting up a GitLab webhook, to control which commands will run automatically when a new PR is opened, you can set the `pr_commands` parameter in the configuration file, similar to the GitHub App: After setting up a GitLab webhook, to control which commands will run automatically when a new PR is opened, you can set the `pr_commands` parameter in the configuration file, similar to the GitHub App:
``` ```
[gitlab] [gitlab]
pr_commands = [ pr_commands = [
"/describe --pr_description.add_original_user_description=true --pr_description.keep_original_user_title=true", "/describe",
"/review --pr_reviewer.num_code_suggestions=0", "/review --pr_reviewer.num_code_suggestions=0",
"/improve", "/improve",
] ]
@ -153,14 +162,14 @@ Each time you invoke a `/review` tool, it will use inline code comments.
### BitBucket Self-Hosted App automatic tools ### BitBucket Self-Hosted App automatic tools
to control which commands will run automatically when a new PR is opened, you can set the `pr_commands` parameter in the configuration file: To control which commands will run automatically when a new PR is opened, you can set the `pr_commands` parameter in the configuration file:
Specifically, set the following values: Specifically, set the following values:
[bitbucket_app]
``` ```
[bitbucket_app]
pr_commands = [ pr_commands = [
"/review --pr_reviewer.num_code_suggestions=0", "/review --pr_reviewer.num_code_suggestions=0",
"/improve --pr_code_suggestions.summarize=false", "/improve --pr_code_suggestions.commitable_code_suggestions=true",
] ]
``` ```
@ -170,16 +179,15 @@ To use Azure DevOps provider use the following settings in configuration.toml:
``` ```
[config] [config]
git_provider="azure" git_provider="azure"
use_repo_settings_file=false
``` ```
Azure DevOps provider supports [PAT token](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows) or [DefaultAzureCredential](https://learn.microsoft.com/en-us/azure/developer/python/sdk/authentication-overview#authentication-in-server-environments) authentication. Azure DevOps provider supports [PAT token](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows) or [DefaultAzureCredential](https://learn.microsoft.com/en-us/azure/developer/python/sdk/authentication-overview#authentication-in-server-environments) authentication.
PAT is faster to create, but has build in experation date, and will use the user identity for API calls. PAT is faster to create, but has build in expiration date, and will use the user identity for API calls.
Using DefaultAzureCredential you can use managed identity or Service principle, which are more secure and will create seperate ADO user identity (via AAD) to the agent. Using DefaultAzureCredential you can use managed identity or Service principle, which are more secure and will create separate ADO user identity (via AAD) to the agent.
If PAT was choosen, you can assign the value in .secrets.toml. If PAT was chosen, you can assign the value in .secrets.toml.
If DefaultAzureCredential was choosen, you can assigned the additional env vars like AZURE_CLIENT_SECRET directly, If DefaultAzureCredential was chosen, you can assigned the additional env vars like AZURE_CLIENT_SECRET directly,
or use managed identity/az cli (for local develpment) without any additional configuration. or use managed identity/az cli (for local development) without any additional configuration.
in any case, 'org' value must be assigned in .secrets.toml: in any case, 'org' value must be assigned in .secrets.toml:
``` ```
[azure_devops] [azure_devops]
@ -193,8 +201,8 @@ To control which commands will run automatically when a new PR is opened, you ca
``` ```
[azure_devops_server] [azure_devops_server]
pr_commands = [ pr_commands = [
"/describe --pr_description.add_original_user_description=true --pr_description.keep_original_user_title=true", "/describe",
"/review --pr_reviewer.num_code_suggestions=0", "/review --pr_reviewer.num_code_suggestions=0",
"/improve", "/improve",
] ]
``` ```

View File

@ -11,19 +11,24 @@ There are three ways to set persistent configurations:
In terms of precedence, wiki configurations will override local configurations, and local configurations will override global configurations. In terms of precedence, wiki configurations will override local configurations, and local configurations will override global configurations.
!!! tip "Tip1: edit only what you need"
Your configuration file should be minimal, and edit only the relevant values. Don't copy the entire configuration options, since it can lead to legacy problems when something changes.
!!! tip "Tip2: show relevant configurations"
If you set `config.output_relevant_configurations=true`, each tool will also output in a collapsible section its relevant configurations. This can be useful for debugging, or getting to know the configurations better.
## Wiki configuration file 💎 ## Wiki configuration file 💎
Specifically for GitHub, with PR-Agent-Pro you can set configurations by creating a page called `.pr_agent.toml` in the [wiki](https://github.com/Codium-ai/pr-agent/wiki/pr_agent.toml) of the repo. Specifically for GitHub, with PR-Agent-Pro you can set configurations by creating a page called `.pr_agent.toml` in the [wiki](https://github.com/Codium-ai/pr-agent/wiki/pr_agent.toml) of the repo.
The advantage of this method is that it allows to set configurations without needing to commit new content to the repo - just edit the wiki page and **save**. The advantage of this method is that it allows to set configurations without needing to commit new content to the repo - just edit the wiki page and **save**.
<kbd><img src="https://codium.ai/images/pr_agent/wiki_configuration.png" width="512"></kbd> ![wiki_configuration](https://codium.ai/images/pr_agent/wiki_configuration.png){width=512}
Click [here](https://codium.ai/images/pr_agent/wiki_configuration_pr_agent.mp4) to see a short instructional video. We recommend surrounding the configuration content with triple-quotes, to allow better presentation when displayed in the wiki as markdown. Click [here](https://codium.ai/images/pr_agent/wiki_configuration_pr_agent.mp4) to see a short instructional video. We recommend surrounding the configuration content with triple-quotes, to allow better presentation when displayed in the wiki as markdown.
An example content: An example content:
``` ```
[pr_description] # /describe # [pr_description]
keep_original_user_title=false generate_ai_title=true
``` ```
PR-Agent will know to remove the triple-quotes when reading the configuration content. PR-Agent will know to remove the triple-quotes when reading the configuration content.
@ -53,4 +58,4 @@ Parameters from a local `.pr_agent.toml` file, in a specific repo, will override
For example, in the GitHub organization `Codium-ai`: For example, in the GitHub organization `Codium-ai`:
- The repo [`https://github.com/Codium-ai/pr-agent-settings`](https://github.com/Codium-ai/pr-agent-settings/blob/main/.pr_agent.toml) contains a `.pr_agent.toml` file that serves as a global configuration file for all the repos in the GitHub organization `Codium-ai`. - The repo [`https://github.com/Codium-ai/pr-agent-settings`](https://github.com/Codium-ai/pr-agent-settings/blob/main/.pr_agent.toml) contains a `.pr_agent.toml` file that serves as a global configuration file for all the repos in the GitHub organization `Codium-ai`.
- The repo [`https://github.com/Codium-ai/pr-agent`](https://github.com/Codium-ai/pr-agent/blob/main/.pr_agent.toml) inherits the global configuration file from `pr-agent-settings`. - The repo [`https://github.com/Codium-ai/pr-agent`](https://github.com/Codium-ai/pr-agent/blob/main/.pr_agent.toml) inherits the global configuration file from `pr-agent-settings`.

View File

@ -1,8 +1,10 @@
# Usage guide # Usage guide
This page provides a detailed guide on how to use PR-Agent. It includes information on how to adjust PR-Agent configurations, define which tools will run automatically, manage mail notifications, and other advanced configurations.
- [Introduction](./introduction.md) - [Introduction](./introduction.md)
- [Configuration Options](./configuration_options.md) - [Configuration Options](./configuration_options.md)
- [Managing Mail Notifications](./mail_notifications.md)
- [Usage and Automation](./automations_and_usage.md) - [Usage and Automation](./automations_and_usage.md)
- [Local Repo (CLI)](./automations_and_usage.md#local-repo-cli) - [Local Repo (CLI)](./automations_and_usage.md#local-repo-cli)
- [Online Usage](./automations_and_usage.md#online-usage) - [Online Usage](./automations_and_usage.md#online-usage)
@ -11,6 +13,7 @@
- [GitLab Webhook](./automations_and_usage.md#gitlab-webhook) - [GitLab Webhook](./automations_and_usage.md#gitlab-webhook)
- [BitBucket App](./automations_and_usage.md#bitbucket-app) - [BitBucket App](./automations_and_usage.md#bitbucket-app)
- [Azure DevOps Provider](./automations_and_usage.md#azure-devops-provider) - [Azure DevOps Provider](./automations_and_usage.md#azure-devops-provider)
- [Managing Mail Notifications](./mail_notifications.md)
- [Additional Configurations Walkthrough](./additional_configurations.md) - [Additional Configurations Walkthrough](./additional_configurations.md)
- [Ignoring files from analysis](./additional_configurations.md#ignoring-files-from-analysis) - [Ignoring files from analysis](./additional_configurations.md#ignoring-files-from-analysis)
- [Extra instructions](./additional_configurations.md#extra-instructions) - [Extra instructions](./additional_configurations.md#extra-instructions)

View File

@ -2,8 +2,17 @@
Unfortunately, it is not possible in GitHub to disable mail notifications from a specific user. Unfortunately, it is not possible in GitHub to disable mail notifications from a specific user.
If you are subscribed to notifications for a repo with PR-Agent, we recommend turning off notifications for PR comments, to avoid lengthy emails: If you are subscribed to notifications for a repo with PR-Agent, we recommend turning off notifications for PR comments, to avoid lengthy emails:
<kbd><img src="https://codium.ai/images/pr_agent/notifications.png" width="512"></kbd> ![notifications](https://codium.ai/images/pr_agent/notifications.png){width=512}
As an alternative, you can filter in your mail provider the notifications specifically from the PR-Agent bot, [see how](https://www.quora.com/How-can-you-filter-emails-for-specific-people-in-Gmail#:~:text=On%20the%20Filters%20and%20Blocked,the%20body%20of%20the%20email). As an alternative, you can filter in your mail provider the notifications specifically from the PR-Agent bot, [see how](https://www.quora.com/How-can-you-filter-emails-for-specific-people-in-Gmail#:~:text=On%20the%20Filters%20and%20Blocked,the%20body%20of%20the%20email).
<kbd><img src="https://codium.ai/images/pr_agent/filter_mail_notifications.png" width="512"></kbd> ![filter_mail_notifications](https://codium.ai/images/pr_agent/filter_mail_notifications.png){width=512}
Another option to reduce the mail overload, yet still receive notifications on PR-Agent tools, is to disable the help collapsible section in PR-Agent bot comments.
This can done by setting `enable_help_text=false` for the relevant tool in the configuration file.
For example, to disable the help text for the `pr_reviewer` tool, set:
```
[pr_reviewer]
enable_help_text = false
```

View File

@ -1,4 +1,6 @@
site_name: PR-Agent site_name: PR-Agent Documentation
repo_url: https://github.com/Codium-ai/pr-agent
repo_name: Codium-ai/pr-agent
nav: nav:
- Overview: 'index.md' - Overview: 'index.md'
@ -9,11 +11,12 @@ nav:
- GitLab: 'installation/gitlab.md' - GitLab: 'installation/gitlab.md'
- BitBucket: 'installation/bitbucket.md' - BitBucket: 'installation/bitbucket.md'
- Azure DevOps: 'installation/azure.md' - Azure DevOps: 'installation/azure.md'
- 💎 PR-Agent Pro: 'installation/pr_agent_pro.md'
- Usage Guide: - Usage Guide:
- 'usage-guide/index.md' - 'usage-guide/index.md'
- Introduction: 'usage-guide/introduction.md' - Introduction: 'usage-guide/introduction.md'
- Configuration Options: 'usage-guide/configuration_options.md' - Configuration Options: 'usage-guide/configuration_options.md'
- Managing email notifications: 'usage-guide/mail_notifications.md' - Managing Mail Notifications: 'usage-guide/mail_notifications.md'
- Usage and Automation: 'usage-guide/automations_and_usage.md' - Usage and Automation: 'usage-guide/automations_and_usage.md'
- Additional Configurations: 'usage-guide/additional_configurations.md' - Additional Configurations: 'usage-guide/additional_configurations.md'
- Tools: - Tools:
@ -24,19 +27,24 @@ nav:
- Ask: 'tools/ask.md' - Ask: 'tools/ask.md'
- Update Changelog: 'tools/update_changelog.md' - Update Changelog: 'tools/update_changelog.md'
- Similar Issues: 'tools/similar_issues.md' - Similar Issues: 'tools/similar_issues.md'
- Help: 'tools/help.md'
- 💎 Analyze: 'tools/analyze.md' - 💎 Analyze: 'tools/analyze.md'
- 💎 Test: 'tools/test.md' - 💎 Test: 'tools/test.md'
- 💎 Improve Component: 'tools/improve_component.md'
- 💎 Documentation: 'tools/documentation.md' - 💎 Documentation: 'tools/documentation.md'
- 💎 Custom Labels: 'tools/custom_labels.md' - 💎 Custom Labels: 'tools/custom_labels.md'
- 💎 Custom Suggestions: 'tools/custom_suggestions.md' - 💎 Custom Prompt: 'tools/custom_prompt.md'
- 💎 CI Feedback: 'tools/ci_feedback.md' - 💎 CI Feedback: 'tools/ci_feedback.md'
- 💎 Similar Code: 'tools/similar_code.md' - 💎 Similar Code: 'tools/similar_code.md'
- Core Abilities: 'core-abilities/index.md' - Core Abilities: 'core-abilities/index.md'
- Chrome Extension: 'chrome-extension/index.md'
theme: theme:
logo: assets/logo.png logo: assets/logo.svg
favicon: assets/favicon.ico favicon: assets/favicon.ico
name: material name: material
icon:
repo: fontawesome/brands/github
features: features:
- navigation.tabs - navigation.tabs
- navigation.expand - navigation.expand
@ -76,6 +84,7 @@ theme:
plugins: plugins:
- social - social
- search - search
- glightbox
extra: extra:
generator: false generator: false
@ -92,6 +101,9 @@ extra:
link: https://twitter.com/CodiumAI link: https://twitter.com/CodiumAI
- icon: fontawesome/brands/instagram - icon: fontawesome/brands/instagram
link: https://www.instagram.com/codiumai/ link: https://www.instagram.com/codiumai/
analytics:
provider: custom
property: ${{ secrets.GOOGLE_ANALYTICS_ID }}
extra_css: extra_css:
- css/custom.css - css/custom.css
@ -108,10 +120,11 @@ markdown_extensions:
- pymdownx.details - pymdownx.details
- pymdownx.superfences - pymdownx.superfences
- pymdownx.mark - pymdownx.mark
- md_in_html
- attr_list - attr_list
- pymdownx.emoji: - pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg emoji_generator: !!python/name:material.extensions.emoji.to_svg
- toc: - toc:
title: On this page title: On this page
toc_depth: 3 toc_depth: 3

10
docs/overrides/main.html Normal file
View File

@ -0,0 +1,10 @@
{% extends "base.html" %}
{% block scripts %}
{{ super() }}
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5C9KZBM3"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
{% endblock %}

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Footer Customization</title> <title>Footer</title>
<style> <style>
body { body {
margin: 0; margin: 0;
@ -27,13 +27,7 @@
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
.footer-links {
display: flex;
justify-content: center;
gap: 20px;
margin: 10px 0;
}
.footer-links, .social-icons { .footer-links, .social-icons {
padding: 0; padding: 0;
list-style-type: none; list-style-type: none;
@ -42,25 +36,46 @@
gap: 20px; gap: 20px;
align-items: center; align-items: center;
} }
.footer-links a:hover {
color: #AEA1F1; .footer-links a:hover, .social-icons a:hover {
}
.social-icons {
display: flex;
gap: 20px;
align-items: center;
}
.social-icons a:hover {
color: #AEA1F1; color: #AEA1F1;
} }
.social-icons svg { .social-icons svg {
width: 24px; width: 24px;
height: auto; height: auto;
fill: white; fill: white;
} }
.footer-text { .footer-text {
width: 240px; width: 240px;
} }
@media (max-width: 768px) {
.container {
flex-direction: column;
align-items: center;
text-align: center;
}
.footer-links, .social-icons, .footer-text {
width: 100%;
justify-content: center;
margin: 10px 0;
}
.footer-links {
order: 1;
}
.social-icons {
order: 2;
}
.footer-text {
order: 3;
}
}
</style> </style>
</head> </head>
<body> <body>

View File

@ -0,0 +1,7 @@
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-5C9KZBM3');</script>
<!-- End Google Tag Manager -->

View File

@ -73,6 +73,9 @@ class PRAgent:
args = update_settings_from_args(args) args = update_settings_from_args(args)
action = action.lstrip("/").lower() action = action.lstrip("/").lower()
if action not in command2class:
get_logger().debug(f"Unknown command: {action}")
return False
with get_logger().contextualize(command=action): with get_logger().contextualize(command=action):
get_logger().info("PR-Agent request handler started", analytics=True) get_logger().info("PR-Agent request handler started", analytics=True)
if action == "reflect_and_review": if action == "reflect_and_review":

View File

@ -1,8 +1,9 @@
MAX_TOKENS = { MAX_TOKENS = {
'text-embedding-ada-002': 8000, 'text-embedding-ada-002': 8000,
'gpt-3.5-turbo': 4000, 'gpt-3.5-turbo': 16000,
'gpt-3.5-turbo-0125': 16000,
'gpt-3.5-turbo-0613': 4000, 'gpt-3.5-turbo-0613': 4000,
'gpt-3.5-turbo-0301': 4000, 'gpt-3.5-turbo-1106': 16000,
'gpt-3.5-turbo-16k': 16000, 'gpt-3.5-turbo-16k': 16000,
'gpt-3.5-turbo-16k-0613': 16000, 'gpt-3.5-turbo-16k-0613': 16000,
'gpt-4': 8000, 'gpt-4': 8000,
@ -10,6 +11,11 @@ MAX_TOKENS = {
'gpt-4-32k': 32000, 'gpt-4-32k': 32000,
'gpt-4-1106-preview': 128000, # 128K, but may be limited by config.max_model_tokens 'gpt-4-1106-preview': 128000, # 128K, but may be limited by config.max_model_tokens
'gpt-4-0125-preview': 128000, # 128K, but may be limited by config.max_model_tokens 'gpt-4-0125-preview': 128000, # 128K, but may be limited by config.max_model_tokens
'gpt-4o': 128000, # 128K, but may be limited by config.max_model_tokens
'gpt-4o-2024-05-13': 128000, # 128K, but may be limited by config.max_model_tokens
'gpt-4-turbo-preview': 128000, # 128K, but may be limited by config.max_model_tokens
'gpt-4-turbo-2024-04-09': 128000, # 128K, but may be limited by config.max_model_tokens
'gpt-4-turbo': 128000, # 128K, but may be limited by config.max_model_tokens
'claude-instant-1': 100000, 'claude-instant-1': 100000,
'claude-2': 100000, 'claude-2': 100000,
'command-nightly': 4096, 'command-nightly': 4096,
@ -23,4 +29,11 @@ MAX_TOKENS = {
'anthropic.claude-v1': 100000, 'anthropic.claude-v1': 100000,
'anthropic.claude-v2': 100000, 'anthropic.claude-v2': 100000,
'anthropic/claude-3-opus-20240229': 100000, 'anthropic/claude-3-opus-20240229': 100000,
'bedrock/anthropic.claude-instant-v1': 100000,
'bedrock/anthropic.claude-v2': 100000,
'bedrock/anthropic.claude-v2:1': 100000,
'bedrock/anthropic.claude-3-sonnet-20240229-v1:0': 100000,
'bedrock/anthropic.claude-3-haiku-20240307-v1:0': 100000,
'groq/llama3-8b-8192': 8192,
'groq/llama3-70b-8192': 8192,
} }

View File

@ -15,7 +15,7 @@ class BaseAiHandler(ABC):
pass pass
@abstractmethod @abstractmethod
async def chat_completion(self, model: str, system: str, user: str, temperature: float = 0.2): async def chat_completion(self, model: str, system: str, user: str, temperature: float = 0.2, img_path: str = None):
""" """
This method should be implemented to return a chat completion from the AI model. This method should be implemented to return a chat completion from the AI model.
Args: Args:

View File

@ -1,5 +1,5 @@
import os import os
import requests
import boto3 import boto3
import litellm import litellm
import openai import openai
@ -36,6 +36,8 @@ class LiteLLMAIHandler(BaseAiHandler):
assert litellm_token, "LITELLM_TOKEN is required" assert litellm_token, "LITELLM_TOKEN is required"
os.environ["LITELLM_TOKEN"] = litellm_token os.environ["LITELLM_TOKEN"] = litellm_token
litellm.use_client = True litellm.use_client = True
if get_settings().get("LITELLM.DROP_PARAMS", None):
litellm.drop_params = get_settings().litellm.drop_params
if get_settings().get("OPENAI.ORG", None): if get_settings().get("OPENAI.ORG", None):
litellm.organization = get_settings().openai.org litellm.organization = get_settings().openai.org
if get_settings().get("OPENAI.API_TYPE", None): if get_settings().get("OPENAI.API_TYPE", None):
@ -50,8 +52,8 @@ class LiteLLMAIHandler(BaseAiHandler):
litellm.anthropic_key = get_settings().anthropic.key litellm.anthropic_key = get_settings().anthropic.key
if get_settings().get("COHERE.KEY", None): if get_settings().get("COHERE.KEY", None):
litellm.cohere_key = get_settings().cohere.key litellm.cohere_key = get_settings().cohere.key
if get_settings().get("REPLICATE.KEY", None): if get_settings().get("GROQ.KEY", None):
litellm.replicate_key = get_settings().replicate.key litellm.api_key = get_settings().groq.key
if get_settings().get("REPLICATE.KEY", None): if get_settings().get("REPLICATE.KEY", None):
litellm.replicate_key = get_settings().replicate.key litellm.replicate_key = get_settings().replicate.key
if get_settings().get("HUGGINGFACE.KEY", None): if get_settings().get("HUGGINGFACE.KEY", None):
@ -59,6 +61,9 @@ class LiteLLMAIHandler(BaseAiHandler):
if get_settings().get("HUGGINGFACE.API_BASE", None) and 'huggingface' in get_settings().config.model: if get_settings().get("HUGGINGFACE.API_BASE", None) and 'huggingface' in get_settings().config.model:
litellm.api_base = get_settings().huggingface.api_base litellm.api_base = get_settings().huggingface.api_base
self.api_base = get_settings().huggingface.api_base self.api_base = get_settings().huggingface.api_base
if get_settings().get("OLLAMA.API_BASE", None) :
litellm.api_base = get_settings().ollama.api_base
self.api_base = get_settings().ollama.api_base
if get_settings().get("HUGGINGFACE.REPITITION_PENALTY", None): if get_settings().get("HUGGINGFACE.REPITITION_PENALTY", None):
self.repetition_penalty = float(get_settings().huggingface.repetition_penalty) self.repetition_penalty = float(get_settings().huggingface.repetition_penalty)
if get_settings().get("VERTEXAI.VERTEX_PROJECT", None): if get_settings().get("VERTEXAI.VERTEX_PROJECT", None):
@ -68,11 +73,24 @@ class LiteLLMAIHandler(BaseAiHandler):
) )
if get_settings().get("AWS.BEDROCK_REGION", None): if get_settings().get("AWS.BEDROCK_REGION", None):
litellm.AmazonAnthropicConfig.max_tokens_to_sample = 2000 litellm.AmazonAnthropicConfig.max_tokens_to_sample = 2000
litellm.AmazonAnthropicClaude3Config.max_tokens = 2000
self.aws_bedrock_client = boto3.client( self.aws_bedrock_client = boto3.client(
service_name="bedrock-runtime", service_name="bedrock-runtime",
region_name=get_settings().aws.bedrock_region, region_name=get_settings().aws.bedrock_region,
) )
def prepare_logs(self, response, system, user, resp, finish_reason):
response_log = response.dict().copy()
response_log['system'] = system
response_log['user'] = user
response_log['output'] = resp
response_log['finish_reason'] = finish_reason
if hasattr(self, 'main_pr_language'):
response_log['main_pr_language'] = self.main_pr_language
else:
response_log['main_pr_language'] = 'unknown'
return response_log
@property @property
def deployment_id(self): def deployment_id(self):
""" """
@ -84,13 +102,27 @@ class LiteLLMAIHandler(BaseAiHandler):
retry=retry_if_exception_type((openai.APIError, openai.APIConnectionError, openai.Timeout)), # No retry on RateLimitError retry=retry_if_exception_type((openai.APIError, openai.APIConnectionError, openai.Timeout)), # No retry on RateLimitError
stop=stop_after_attempt(OPENAI_RETRIES) stop=stop_after_attempt(OPENAI_RETRIES)
) )
async def chat_completion(self, model: str, system: str, user: str, temperature: float = 0.2): async def chat_completion(self, model: str, system: str, user: str, temperature: float = 0.2, img_path: str = None):
try: try:
resp, finish_reason = None, None resp, finish_reason = None, None
deployment_id = self.deployment_id deployment_id = self.deployment_id
if self.azure: if self.azure:
model = 'azure/' + model model = 'azure/' + model
messages = [{"role": "system", "content": system}, {"role": "user", "content": user}] messages = [{"role": "system", "content": system}, {"role": "user", "content": user}]
if img_path:
try:
# check if the image link is alive
r = requests.head(img_path, allow_redirects=True)
if r.status_code == 404:
error_msg = f"The image link is not [alive](img_path).\nPlease repost the original image as a comment, and send the question again with 'quote reply' (see [instructions](https://pr-agent-docs.codium.ai/tools/ask/#ask-on-images-using-the-pr-code-as-context))."
get_logger().error(error_msg)
return f"{error_msg}", "error"
except Exception as e:
get_logger().error(f"Error fetching image: {img_path}", e)
return f"Error fetching image: {img_path}", "error"
messages[1]["content"] = [{"type": "text", "text": messages[1]["content"]},
{"type": "image_url", "image_url": {"url": img_path}}]
kwargs = { kwargs = {
"model": model, "model": model,
"deployment_id": deployment_id, "deployment_id": deployment_id,
@ -125,11 +157,14 @@ class LiteLLMAIHandler(BaseAiHandler):
else: else:
resp = response["choices"][0]['message']['content'] resp = response["choices"][0]['message']['content']
finish_reason = response["choices"][0]["finish_reason"] finish_reason = response["choices"][0]["finish_reason"]
# usage = response.get("usage")
get_logger().debug(f"\nAI response:\n{resp}") get_logger().debug(f"\nAI response:\n{resp}")
get_logger().debug("Full_response", artifact=response)
# log the full response for debugging
response_log = self.prepare_logs(response, system, user, resp, finish_reason)
get_logger().debug("Full_response", artifact=response_log)
# for CLI debugging
if get_settings().config.verbosity_level >= 2: if get_settings().config.verbosity_level >= 2:
get_logger().info(f"\nAI response:\n{resp}") get_logger().info(f"\nAI response:\n{resp}")
return resp, finish_reason return resp, finish_reason

View File

@ -9,7 +9,7 @@ from pr_agent.algo.git_patch_processing import convert_to_hunks_with_lines_numbe
from pr_agent.algo.language_handler import sort_files_by_main_languages from pr_agent.algo.language_handler import sort_files_by_main_languages
from pr_agent.algo.file_filter import filter_ignored from pr_agent.algo.file_filter import filter_ignored
from pr_agent.algo.token_handler import TokenHandler from pr_agent.algo.token_handler import TokenHandler
from pr_agent.algo.utils import get_max_tokens, ModelType from pr_agent.algo.utils import get_max_tokens, clip_tokens, ModelType
from pr_agent.config_loader import get_settings from pr_agent.config_loader import get_settings
from pr_agent.git_providers.git_provider import GitProvider from pr_agent.git_providers.git_provider import GitProvider
from pr_agent.algo.types import EDIT_TYPE, FilePatchInfo from pr_agent.algo.types import EDIT_TYPE, FilePatchInfo
@ -87,22 +87,34 @@ def get_pr_diff(git_provider: GitProvider, token_handler: TokenHandler, model: s
# if we are over the limit, start pruning # if we are over the limit, start pruning
get_logger().info(f"Tokens: {total_tokens}, total tokens over limit: {get_max_tokens(model)}, " get_logger().info(f"Tokens: {total_tokens}, total tokens over limit: {get_max_tokens(model)}, "
f"pruning diff.") f"pruning diff.")
patches_compressed, modified_file_names, deleted_file_names, added_file_names = \ patches_compressed, modified_file_names, deleted_file_names, added_file_names, total_tokens_new = \
pr_generate_compressed_diff(pr_languages, token_handler, model, add_line_numbers_to_hunks) pr_generate_compressed_diff(pr_languages, token_handler, model, add_line_numbers_to_hunks)
# Insert additional information about added, modified, and deleted files if there is enough space
max_tokens = get_max_tokens(model) - OUTPUT_BUFFER_TOKENS_HARD_THRESHOLD
curr_token = total_tokens_new # == token_handler.count_tokens(final_diff)+token_handler.prompt_tokens
final_diff = "\n".join(patches_compressed) final_diff = "\n".join(patches_compressed)
if added_file_names: delta_tokens = 10
if added_file_names and (max_tokens - curr_token) > delta_tokens:
added_list_str = ADDED_FILES_ + "\n".join(added_file_names) added_list_str = ADDED_FILES_ + "\n".join(added_file_names)
final_diff = final_diff + "\n\n" + added_list_str added_list_str = clip_tokens(added_list_str, max_tokens - curr_token)
if modified_file_names: if added_list_str:
final_diff = final_diff + "\n\n" + added_list_str
curr_token += token_handler.count_tokens(added_list_str) + 2
if modified_file_names and (max_tokens - curr_token) > delta_tokens:
modified_list_str = MORE_MODIFIED_FILES_ + "\n".join(modified_file_names) modified_list_str = MORE_MODIFIED_FILES_ + "\n".join(modified_file_names)
final_diff = final_diff + "\n\n" + modified_list_str modified_list_str = clip_tokens(modified_list_str, max_tokens - curr_token)
if deleted_file_names: if modified_list_str:
final_diff = final_diff + "\n\n" + modified_list_str
curr_token += token_handler.count_tokens(modified_list_str) + 2
if deleted_file_names and (max_tokens - curr_token) > delta_tokens:
deleted_list_str = DELETED_FILES_ + "\n".join(deleted_file_names) deleted_list_str = DELETED_FILES_ + "\n".join(deleted_file_names)
final_diff = final_diff + "\n\n" + deleted_list_str deleted_list_str = clip_tokens(deleted_list_str, max_tokens - curr_token)
if deleted_list_str:
final_diff = final_diff + "\n\n" + deleted_list_str
try: try:
get_logger().debug(f"After pruning, added_list_str: {added_list_str}, modified_list_str: {modified_list_str}, " get_logger().debug(f"After pruning, added_list_str: {added_list_str}, modified_list_str: {modified_list_str}, "
f"deleted_list_str: {deleted_list_str}") f"deleted_list_str: {deleted_list_str}")
except Exception as e: except Exception as e:
pass pass
return final_diff return final_diff
@ -149,7 +161,7 @@ def pr_generate_extended_diff(pr_languages: list,
def pr_generate_compressed_diff(top_langs: list, token_handler: TokenHandler, model: str, def pr_generate_compressed_diff(top_langs: list, token_handler: TokenHandler, model: str,
convert_hunks_to_line_numbers: bool) -> Tuple[list, list, list, list]: convert_hunks_to_line_numbers: bool) -> Tuple[list, list, list, list, int]:
""" """
Generate a compressed diff string for a pull request, using diff minimization techniques to reduce the number of Generate a compressed diff string for a pull request, using diff minimization techniques to reduce the number of
tokens used. tokens used.
@ -195,10 +207,11 @@ def pr_generate_compressed_diff(top_langs: list, token_handler: TokenHandler, mo
patch = handle_patch_deletions(patch, original_file_content_str, patch = handle_patch_deletions(patch, original_file_content_str,
new_file_content_str, file.filename, file.edit_type) new_file_content_str, file.filename, file.edit_type)
if patch is None: if patch is None:
if not deleted_files_list: # if not deleted_files_list:
total_tokens += token_handler.count_tokens(DELETED_FILES_) # total_tokens += token_handler.count_tokens(DELETED_FILES_)
deleted_files_list.append(file.filename) if file.filename not in deleted_files_list:
total_tokens += token_handler.count_tokens(file.filename) + 1 deleted_files_list.append(file.filename)
# total_tokens += token_handler.count_tokens(file.filename) + 1
continue continue
if convert_hunks_to_line_numbers: if convert_hunks_to_line_numbers:
@ -219,14 +232,17 @@ def pr_generate_compressed_diff(top_langs: list, token_handler: TokenHandler, mo
if get_settings().config.verbosity_level >= 2: if get_settings().config.verbosity_level >= 2:
get_logger().warning(f"Patch too large, minimizing it, {file.filename}") get_logger().warning(f"Patch too large, minimizing it, {file.filename}")
if file.edit_type == EDIT_TYPE.ADDED: if file.edit_type == EDIT_TYPE.ADDED:
if not added_files_list: # if not added_files_list:
total_tokens += token_handler.count_tokens(ADDED_FILES_) # total_tokens += token_handler.count_tokens(ADDED_FILES_)
added_files_list.append(file.filename) if file.filename not in added_files_list:
added_files_list.append(file.filename)
# total_tokens += token_handler.count_tokens(file.filename) + 1
else: else:
if not modified_files_list: # if not modified_files_list:
total_tokens += token_handler.count_tokens(MORE_MODIFIED_FILES_) # total_tokens += token_handler.count_tokens(MORE_MODIFIED_FILES_)
modified_files_list.append(file.filename) if file.filename not in modified_files_list:
total_tokens += token_handler.count_tokens(file.filename) + 1 modified_files_list.append(file.filename)
# total_tokens += token_handler.count_tokens(file.filename) + 1
continue continue
if patch: if patch:
@ -239,7 +255,7 @@ def pr_generate_compressed_diff(top_langs: list, token_handler: TokenHandler, mo
if get_settings().config.verbosity_level >= 2: if get_settings().config.verbosity_level >= 2:
get_logger().info(f"Tokens: {total_tokens}, last filename: {file.filename}") get_logger().info(f"Tokens: {total_tokens}, last filename: {file.filename}")
return patches, modified_files_list, deleted_files_list, added_files_list return patches, modified_files_list, deleted_files_list, added_files_list, total_tokens
async def retry_with_fallback_models(f: Callable, model_type: ModelType = ModelType.REGULAR): async def retry_with_fallback_models(f: Callable, model_type: ModelType = ModelType.REGULAR):
@ -382,4 +398,4 @@ def get_pr_multi_diffs(git_provider: GitProvider,
final_diff = "\n".join(patches) final_diff = "\n".join(patches)
final_diff_list.append(final_diff) final_diff_list.append(final_diff)
return final_diff_list return final_diff_list

View File

@ -1,12 +1,25 @@
from jinja2 import Environment, StrictUndefined from jinja2 import Environment, StrictUndefined
from tiktoken import encoding_for_model, get_encoding from tiktoken import encoding_for_model, get_encoding
from pr_agent.config_loader import get_settings from pr_agent.config_loader import get_settings
from threading import Lock
def get_token_encoder(): class TokenEncoder:
return encoding_for_model(get_settings().config.model) if "gpt" in get_settings().config.model else get_encoding( _encoder_instance = None
"cl100k_base") _model = None
_lock = Lock() # Create a lock object
@classmethod
def get_token_encoder(cls):
model = get_settings().config.model
if cls._encoder_instance is None or model != cls._model: # Check without acquiring the lock for performance
with cls._lock: # Lock acquisition to ensure thread safety
if cls._encoder_instance is None or model != cls._model:
cls._model = model
cls._encoder_instance = encoding_for_model(cls._model) if "gpt" in cls._model else get_encoding(
"cl100k_base")
return cls._encoder_instance
class TokenHandler: class TokenHandler:
""" """
@ -31,7 +44,7 @@ class TokenHandler:
- system: The system string. - system: The system string.
- user: The user string. - user: The user string.
""" """
self.encoder = get_token_encoder() self.encoder = TokenEncoder.get_token_encoder()
if pr is not None: if pr is not None:
self.prompt_tokens = self._get_system_user_tokens(pr, self.encoder, vars, system, user) self.prompt_tokens = self._get_system_user_tokens(pr, self.encoder, vars, system, user)

View File

@ -2,6 +2,7 @@ from __future__ import annotations
import difflib import difflib
import json import json
import os
import re import re
import textwrap import textwrap
from datetime import datetime from datetime import datetime
@ -12,7 +13,7 @@ import yaml
from starlette_context import context from starlette_context import context
from pr_agent.algo import MAX_TOKENS from pr_agent.algo import MAX_TOKENS
from pr_agent.algo.token_handler import get_token_encoder from pr_agent.algo.token_handler import TokenEncoder
from pr_agent.config_loader import get_settings, global_settings from pr_agent.config_loader import get_settings, global_settings
from pr_agent.algo.types import FilePatchInfo from pr_agent.algo.types import FilePatchInfo
from pr_agent.log import get_logger from pr_agent.log import get_logger
@ -67,10 +68,11 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool = True, increment
output_data (dict): A dictionary containing data to be converted to markdown format. output_data (dict): A dictionary containing data to be converted to markdown format.
Returns: Returns:
str: The markdown formatted text generated from the input dictionary. str: The markdown formatted text generated from the input dictionary.
""" """
emojis = { emojis = {
"Possible issues": "🔍", "Can be split": "🔀",
"Possible issues": "",
"Score": "🏅", "Score": "🏅",
"Relevant tests": "🧪", "Relevant tests": "🧪",
"Focused PR": "", "Focused PR": "",
@ -81,9 +83,9 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool = True, increment
} }
markdown_text = "" markdown_text = ""
if not incremental_review: if not incremental_review:
markdown_text += f"## PR Review\n\n" markdown_text += f"## PR Review 🔍\n\n"
else: else:
markdown_text += f"## Incremental PR Review\n\n" markdown_text += f"## Incremental PR Review 🔍 \n\n"
markdown_text += f"⏮️ Review for commits since previous PR-Agent review {incremental_review}.\n\n" markdown_text += f"⏮️ Review for commits since previous PR-Agent review {incremental_review}.\n\n"
if gfm_supported: if gfm_supported:
markdown_text += "<table>\n<tr>\n" markdown_text += "<table>\n<tr>\n"
@ -94,7 +96,8 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool = True, increment
for key, value in output_data['review'].items(): for key, value in output_data['review'].items():
if value is None or value == '' or value == {} or value == []: if value is None or value == '' or value == {} or value == []:
continue if key.lower() != 'can_be_split':
continue
key_nice = key.replace('_', ' ').capitalize() key_nice = key.replace('_', ' ').capitalize()
emoji = emojis.get(key_nice, "") emoji = emojis.get(key_nice, "")
if gfm_supported: if gfm_supported:
@ -103,6 +106,8 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool = True, increment
if 'security concerns' in key_nice.lower(): if 'security concerns' in key_nice.lower():
value = emphasize_header(value.strip()) value = emphasize_header(value.strip())
markdown_text += f"<tr><td> {emoji}&nbsp;<strong>{key_nice}</strong></td><td>\n\n{value}\n\n</td></tr>\n" markdown_text += f"<tr><td> {emoji}&nbsp;<strong>{key_nice}</strong></td><td>\n\n{value}\n\n</td></tr>\n"
elif 'can be split' in key_nice.lower():
markdown_text += process_can_be_split(emoji, value)
elif 'possible issues' in key_nice.lower(): elif 'possible issues' in key_nice.lower():
value = value.strip() value = value.strip()
issues = value.split('\n- ') issues = value.split('\n- ')
@ -154,6 +159,38 @@ def convert_to_markdown(output_data: dict, gfm_supported: bool = True, increment
return markdown_text return markdown_text
def process_can_be_split(emoji, value):
# key_nice = "Can this PR be split?"
key_nice = "Multiple PR themes"
markdown_text = ""
if not value or isinstance(value, list) and len(value) == 1:
value = "No"
markdown_text += f"<tr><td> {emoji}&nbsp;<strong>{key_nice}</strong></td><td>\n\n{value}\n\n</td></tr>\n"
else:
number_of_splits = len(value)
markdown_text += f"<tr><td rowspan={number_of_splits}> {emoji}&nbsp;<strong>{key_nice}</strong></td>\n"
for i, split in enumerate(value):
title = split.get('title', '')
relevant_files = split.get('relevant_files', [])
if i == 0:
markdown_text += f"<td><details><summary>\nSub-PR theme: <strong>{title}</strong></summary>\n\n"
markdown_text += f"<hr>\n"
markdown_text += f"Relevant files:\n"
markdown_text += f"<ul>\n"
for file in relevant_files:
markdown_text += f"<li>{file}</li>\n"
markdown_text += f"</ul>\n\n</details></td></tr>\n"
else:
markdown_text += f"<tr>\n<td><details><summary>\nSub-PR theme: <strong>{title}</strong></summary>\n\n"
markdown_text += f"<hr>\n"
markdown_text += f"Relevant files:\n"
markdown_text += f"<ul>\n"
for file in relevant_files:
markdown_text += f"<li>{file}</li>\n"
markdown_text += f"</ul>\n\n</details></td></tr>\n"
return markdown_text
def parse_code_suggestion(code_suggestion: dict, i: int = 0, gfm_supported: bool = True) -> str: def parse_code_suggestion(code_suggestion: dict, i: int = 0, gfm_supported: bool = True) -> str:
""" """
Convert a dictionary of data into markdown format. Convert a dictionary of data into markdown format.
@ -319,7 +356,7 @@ def convert_str_to_datetime(date_str):
return datetime.strptime(date_str, datetime_format) return datetime.strptime(date_str, datetime_format)
def load_large_diff(filename, new_file_content_str: str, original_file_content_str: str) -> str: def load_large_diff(filename, new_file_content_str: str, original_file_content_str: str, show_warning: bool = True) -> str:
""" """
Generate a patch for a modified file by comparing the original content of the file with the new content provided as Generate a patch for a modified file by comparing the original content of the file with the new content provided as
input. input.
@ -338,7 +375,7 @@ def load_large_diff(filename, new_file_content_str: str, original_file_content_s
try: try:
diff = difflib.unified_diff(original_file_content_str.splitlines(keepends=True), diff = difflib.unified_diff(original_file_content_str.splitlines(keepends=True),
new_file_content_str.splitlines(keepends=True)) new_file_content_str.splitlines(keepends=True))
if get_settings().config.verbosity_level >= 2: if get_settings().config.verbosity_level >= 2 and show_warning:
get_logger().warning(f"File was modified, but no patch was found. Manually creating patch: {filename}.") get_logger().warning(f"File was modified, but no patch was found. Manually creating patch: {filename}.")
patch = ''.join(diff) patch = ''.join(diff)
except Exception: except Exception:
@ -530,7 +567,7 @@ def clip_tokens(text: str, max_tokens: int, add_three_dots=True) -> str:
return text return text
try: try:
encoder = get_token_encoder() encoder = TokenEncoder.get_token_encoder()
num_input_tokens = len(encoder.encode(text)) num_input_tokens = len(encoder.encode(text))
if num_input_tokens <= max_tokens: if num_input_tokens <= max_tokens:
return text return text
@ -539,7 +576,7 @@ def clip_tokens(text: str, max_tokens: int, add_three_dots=True) -> str:
num_output_chars = int(chars_per_token * max_tokens) num_output_chars = int(chars_per_token * max_tokens)
clipped_text = text[:num_output_chars] clipped_text = text[:num_output_chars]
if add_three_dots: if add_three_dots:
clipped_text += "...(truncated)" clipped_text += "\n...(truncated)"
return clipped_text return clipped_text
except Exception as e: except Exception as e:
get_logger().warning(f"Failed to clip tokens: {e}") get_logger().warning(f"Failed to clip tokens: {e}")
@ -625,3 +662,38 @@ def find_line_number_of_relevant_line_in_file(diff_files: List[FilePatchInfo],
absolute_position = start2 + delta - 1 absolute_position = start2 + delta - 1
break break
return position, absolute_position return position, absolute_position
def github_action_output(output_data: dict, key_name: str):
try:
if not get_settings().get('github_action_config.enable_output', False):
return
key_data = output_data.get(key_name, {})
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
print(f"{key_name}={json.dumps(key_data, indent=None, ensure_ascii=False)}", file=fh)
except Exception as e:
get_logger().error(f"Failed to write to GitHub Action output: {e}")
return
def show_relevant_configurations(relevant_section: str) -> str:
forbidden_keys = ['ai_disclaimer', 'ai_disclaimer_title', 'ANALYTICS_FOLDER', 'secret_provider',
'trial_prefix_message', 'no_eligible_message', 'identity_provider', 'ALLOWED_REPOS','APP_NAME']
markdown_text = ""
markdown_text += "\n<hr>\n<details> <summary><strong>🛠️ Relevant configurations:</strong></summary> \n\n"
markdown_text +="<br>These are the relevant [configurations](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml) for this tool:\n\n"
markdown_text += f"**[config**]\n```yaml\n\n"
for key, value in get_settings().config.items():
if key in forbidden_keys:
continue
markdown_text += f"{key}: {value}\n"
markdown_text += "\n```\n"
markdown_text += f"\n**[{relevant_section}]**\n```yaml\n\n"
for key, value in get_settings().get(relevant_section, {}).items():
if key in forbidden_keys:
continue
markdown_text += f"{key}: {value}\n"
markdown_text += "\n```"
markdown_text += "\n</details>\n"
return markdown_text

View File

@ -9,48 +9,59 @@ from pr_agent.log import setup_logger
log_level = os.environ.get("LOG_LEVEL", "INFO") log_level = os.environ.get("LOG_LEVEL", "INFO")
setup_logger(log_level) setup_logger(log_level)
def set_parser():
def run(inargs=None):
parser = argparse.ArgumentParser(description='AI based pull request analyzer', usage= parser = argparse.ArgumentParser(description='AI based pull request analyzer', usage=
"""\ """\
Usage: cli.py --pr-url=<URL on supported git hosting service> <command> [<args>]. Usage: cli.py --pr-url=<URL on supported git hosting service> <command> [<args>].
For example: For example:
- cli.py --pr_url=... review - cli.py --pr_url=... review
- cli.py --pr_url=... describe - cli.py --pr_url=... describe
- cli.py --pr_url=... improve - cli.py --pr_url=... improve
- cli.py --pr_url=... ask "write me a poem about this PR" - cli.py --pr_url=... ask "write me a poem about this PR"
- cli.py --pr_url=... reflect - cli.py --pr_url=... reflect
- cli.py --issue_url=... similar_issue - cli.py --issue_url=... similar_issue
Supported commands: Supported commands:
- review / review_pr - Add a review that includes a summary of the PR and specific suggestions for improvement. - review / review_pr - Add a review that includes a summary of the PR and specific suggestions for improvement.
- ask / ask_question [question] - Ask a question about the PR. - ask / ask_question [question] - Ask a question about the PR.
- describe / describe_pr - Modify the PR title and description based on the PR's contents. - describe / describe_pr - Modify the PR title and description based on the PR's contents.
- improve / improve_code - Suggest improvements to the code in the PR as pull request comments ready to commit. - improve / improve_code - Suggest improvements to the code in the PR as pull request comments ready to commit.
Extended mode ('improve --extended') employs several calls, and provides a more thorough feedback Extended mode ('improve --extended') employs several calls, and provides a more thorough feedback
- reflect - Ask the PR author questions about the PR. - reflect - Ask the PR author questions about the PR.
- update_changelog - Update the changelog based on the PR's contents. - update_changelog - Update the changelog based on the PR's contents.
- add_docs - add_docs
- generate_labels - generate_labels
Configuration: Configuration:
To edit any configuration parameter from 'configuration.toml', just add -config_path=<value>. To edit any configuration parameter from 'configuration.toml', just add -config_path=<value>.
For example: 'python cli.py --pr_url=... review --pr_reviewer.extra_instructions="focus on the file: ..."' For example: 'python cli.py --pr_url=... review --pr_reviewer.extra_instructions="focus on the file: ..."'
""") """)
parser.add_argument('--pr_url', type=str, help='The URL of the PR to review', default=None) parser.add_argument('--pr_url', type=str, help='The URL of the PR to review', default=None)
parser.add_argument('--issue_url', type=str, help='The URL of the Issue to review', default=None) parser.add_argument('--issue_url', type=str, help='The URL of the Issue to review', default=None)
parser.add_argument('command', type=str, help='The', choices=commands, default='review') parser.add_argument('command', type=str, help='The', choices=commands, default='review')
parser.add_argument('rest', nargs=argparse.REMAINDER, default=[]) parser.add_argument('rest', nargs=argparse.REMAINDER, default=[])
args = parser.parse_args(inargs) return parser
def run_command(pr_url, command):
# Preparing the command
run_command_str = f"--pr_url={pr_url} {command.lstrip('/')}"
args = set_parser().parse_args(run_command_str.split())
# Run the command. Feedback will appear in GitHub PR comments
run(args=args)
def run(inargs=None, args=None):
parser = set_parser()
if not args:
args = parser.parse_args(inargs)
if not args.pr_url and not args.issue_url: if not args.pr_url and not args.issue_url:
parser.print_help() parser.print_help()
return return

23
pr_agent/cli_pip.py Normal file
View File

@ -0,0 +1,23 @@
from pr_agent import cli
from pr_agent.config_loader import get_settings
def main():
# Fill in the following values
provider = "github" # GitHub provider
user_token = "..." # GitHub user token
openai_key = "..." # OpenAI key
pr_url = "..." # PR URL, for example 'https://github.com/Codium-ai/pr-agent/pull/809'
command = "/review" # Command to run (e.g. '/review', '/describe', '/ask="What is the purpose of this PR?"')
# Setting the configurations
get_settings().set("CONFIG.git_provider", provider)
get_settings().set("openai.key", openai_key)
get_settings().set("github.user_token", user_token)
# Run the command. Feedback will appear in GitHub PR comments
cli.run_command(pr_url, command)
if __name__ == '__main__':
main()

View File

@ -21,6 +21,7 @@ global_settings = Dynaconf(
"settings/pr_line_questions_prompts.toml", "settings/pr_line_questions_prompts.toml",
"settings/pr_description_prompts.toml", "settings/pr_description_prompts.toml",
"settings/pr_code_suggestions_prompts.toml", "settings/pr_code_suggestions_prompts.toml",
"settings/pr_code_suggestions_reflect_prompts.toml",
"settings/pr_sort_code_suggestions_prompts.toml", "settings/pr_sort_code_suggestions_prompts.toml",
"settings/pr_information_from_user_prompts.toml", "settings/pr_information_from_user_prompts.toml",
"settings/pr_update_changelog_prompts.toml", "settings/pr_update_changelog_prompts.toml",

View File

@ -26,6 +26,7 @@ try:
CommentThread, CommentThread,
GitVersionDescriptor, GitVersionDescriptor,
GitPullRequest, GitPullRequest,
GitPullRequestIterationChanges,
) )
except ImportError: except ImportError:
AZURE_DEVOPS_AVAILABLE = False AZURE_DEVOPS_AVAILABLE = False
@ -165,7 +166,7 @@ class AzureDevopsProvider(GitProvider):
except Exception as e: except Exception as e:
get_logger().exception(f"Failed to publish labels, error: {e}") get_logger().exception(f"Failed to publish labels, error: {e}")
def get_pr_labels(self): def get_pr_labels(self, update=False):
try: try:
labels = self.azure_devops_client.get_pull_request_labels( labels = self.azure_devops_client.get_pull_request_labels(
project=self.workspace_slug, project=self.workspace_slug,
@ -230,29 +231,58 @@ class AzureDevopsProvider(GitProvider):
base_sha = self.pr.last_merge_target_commit base_sha = self.pr.last_merge_target_commit
head_sha = self.pr.last_merge_source_commit head_sha = self.pr.last_merge_source_commit
commits = self.azure_devops_client.get_pull_request_commits( # Get PR iterations
project=self.workspace_slug, iterations = self.azure_devops_client.get_pull_request_iterations(
repository_id=self.repo_slug, repository_id=self.repo_slug,
pull_request_id=self.pr_num, pull_request_id=self.pr_num,
project=self.workspace_slug
) )
changes = None
if iterations:
iteration_id = iterations[-1].id # Get the last iteration (most recent changes)
# Get changes for the iteration
changes = self.azure_devops_client.get_pull_request_iteration_changes(
repository_id=self.repo_slug,
pull_request_id=self.pr_num,
iteration_id=iteration_id,
project=self.workspace_slug
)
diff_files = [] diff_files = []
diffs = [] diffs = []
diff_types = {} diff_types = {}
if changes:
for change in changes.change_entries:
item = change.additional_properties.get('item', {})
path = item.get('path', None)
if path:
diffs.append(path)
diff_types[path] = change.additional_properties.get('changeType', 'Unknown')
for c in commits: # wrong implementation - gets all the files that were changed in any commit in the PR
changes_obj = self.azure_devops_client.get_changes( # commits = self.azure_devops_client.get_pull_request_commits(
project=self.workspace_slug, # project=self.workspace_slug,
repository_id=self.repo_slug, # repository_id=self.repo_slug,
commit_id=c.commit_id, # pull_request_id=self.pr_num,
) # )
for i in changes_obj.changes: #
if i["item"]["gitObjectType"] == "tree": # diff_files = []
continue # diffs = []
diffs.append(i["item"]["path"]) # diff_types = {}
diff_types[i["item"]["path"]] = i["changeType"]
diffs = list(set(diffs)) # for c in commits:
# changes_obj = self.azure_devops_client.get_changes(
# project=self.workspace_slug,
# repository_id=self.repo_slug,
# commit_id=c.commit_id,
# )
# for i in changes_obj.changes:
# if i["item"]["gitObjectType"] == "tree":
# continue
# diffs.append(i["item"]["path"])
# diff_types[i["item"]["path"]] = i["changeType"]
#
# diffs = list(set(diffs))
for file in diffs: for file in diffs:
if not is_valid_file(file): if not is_valid_file(file):
@ -273,12 +303,13 @@ class AzureDevopsProvider(GitProvider):
new_file_content_str = new_file_content_str.content new_file_content_str = new_file_content_str.content
except Exception as error: except Exception as error:
get_logger().error( get_logger().error(f"Failed to retrieve new file content of {file} at version {version}. Error: {str(error)}")
"Failed to retrieve new file content of %s at version %s. Error: %s", # get_logger().error(
file, # "Failed to retrieve new file content of %s at version %s. Error: %s",
version, # file,
str(error), # version,
) # str(error),
# )
new_file_content_str = "" new_file_content_str = ""
edit_type = EDIT_TYPE.MODIFIED edit_type = EDIT_TYPE.MODIFIED
@ -303,17 +334,12 @@ class AzureDevopsProvider(GitProvider):
) )
original_file_content_str = original_file_content_str.content original_file_content_str = original_file_content_str.content
except Exception as error: except Exception as error:
get_logger().error( get_logger().error(f"Failed to retrieve original file content of {file} at version {version}. Error: {str(error)}")
"Failed to retrieve original file content of %s at version %s. Error: %s",
file,
version,
str(error),
)
original_file_content_str = "" original_file_content_str = ""
patch = load_large_diff( patch = load_large_diff(
file, new_file_content_str, original_file_content_str file, new_file_content_str, original_file_content_str, show_warning=False
) ).rstrip()
diff_files.append( diff_files.append(
FilePatchInfo( FilePatchInfo(

View File

@ -404,5 +404,5 @@ class BitbucketProvider(GitProvider):
pass pass
# bitbucket does not support labels # bitbucket does not support labels
def get_pr_labels(self): def get_pr_labels(self, update=False):
pass pass

View File

@ -347,7 +347,7 @@ class BitbucketServerProvider(GitProvider):
pass pass
# bitbucket does not support labels # bitbucket does not support labels
def get_pr_labels(self): def get_pr_labels(self, update=False):
pass pass
def _get_pr_comments_url(self): def _get_pr_comments_url(self):

View File

@ -10,7 +10,7 @@ from ..algo.utils import load_large_diff
from .git_provider import GitProvider from .git_provider import GitProvider
from ..config_loader import get_settings from ..config_loader import get_settings
from ..log import get_logger from ..log import get_logger
from pr_agent.algo.language_handler import is_valid_file
class PullRequestCCMimic: class PullRequestCCMimic:
""" """
@ -216,7 +216,7 @@ class CodeCommitProvider(GitProvider):
def publish_labels(self, labels): def publish_labels(self, labels):
return [""] # not implemented yet return [""] # not implemented yet
def get_pr_labels(self): def get_pr_labels(self, update=False):
return [""] # not implemented yet return [""] # not implemented yet
def remove_initial_comment(self): def remove_initial_comment(self):

View File

@ -208,7 +208,7 @@ class GerritProvider(GitProvider):
Comment = namedtuple('Comment', ['body']) Comment = namedtuple('Comment', ['body'])
return Comments([Comment(c['message']) for c in reversed(comments)]) return Comments([Comment(c['message']) for c in reversed(comments)])
def get_pr_labels(self): def get_pr_labels(self, update=False):
raise NotImplementedError( raise NotImplementedError(
'Getting labels is not implemented for the gerrit provider') 'Getting labels is not implemented for the gerrit provider')

View File

@ -71,7 +71,7 @@ class GitProvider(ABC):
# if the existing description was generated by the pr-agent, but it doesn't contain a user description, # if the existing description was generated by the pr-agent, but it doesn't contain a user description,
# return nothing (empty string) because it means there is no user description # return nothing (empty string) because it means there is no user description
user_description_header = "## **user description**" user_description_header = "### **user description**"
if user_description_header not in description_lowercase: if user_description_header not in description_lowercase:
get_logger().info(f"Existing description was generated by the pr-agent, but it doesn't contain a user description") get_logger().info(f"Existing description was generated by the pr-agent, but it doesn't contain a user description")
return "" return ""
@ -102,8 +102,8 @@ class GitProvider(ABC):
return original_user_description return original_user_description
def _possible_headers(self): def _possible_headers(self):
return ("## **user description**", "## **pr type**", "## **pr description**", "## **pr labels**", "## **type**", "## **description**", return ("### **user description**", "### **pr type**", "### **pr description**", "### **pr labels**", "### **type**", "### **description**",
"## **labels**", "### 🤖 generated by pr agent") "### **labels**", "### 🤖 generated by pr agent")
def _is_generated_by_pr_agent(self, description_lowercase: str) -> bool: def _is_generated_by_pr_agent(self, description_lowercase: str) -> bool:
possible_headers = self._possible_headers() possible_headers = self._possible_headers()
@ -164,7 +164,7 @@ class GitProvider(ABC):
pass pass
@abstractmethod @abstractmethod
def get_pr_labels(self): def get_pr_labels(self, update=False):
pass pass
def get_repo_labels(self): def get_repo_labels(self):
@ -197,6 +197,12 @@ class GitProvider(ABC):
def calc_pr_statistics(self, pull_request_data: dict): def calc_pr_statistics(self, pull_request_data: dict):
return {} return {}
def get_num_of_files(self):
try:
return len(self.get_diff_files())
except Exception as e:
return -1
def get_main_pr_language(languages, files) -> str: def get_main_pr_language(languages, files) -> str:
""" """
@ -266,6 +272,7 @@ def get_main_pr_language(languages, files) -> str:
return main_language_str return main_language_str
class IncrementalPR: class IncrementalPR:
def __init__(self, is_incremental: bool = False): def __init__(self, is_incremental: bool = False):
self.is_incremental = is_incremental self.is_incremental = is_incremental

View File

@ -114,6 +114,11 @@ class GithubProvider(GitProvider):
self.git_files = self.pr.get_files() self.git_files = self.pr.get_files()
return self.git_files return self.git_files
def get_num_of_files(self):
if self.git_files:
return self.git_files.totalCount
else:
return -1
@retry(exceptions=RateLimitExceeded, @retry(exceptions=RateLimitExceeded,
tries=get_settings().github.ratelimit_retries, delay=2, backoff=2, jitter=(1, 3)) tries=get_settings().github.ratelimit_retries, delay=2, backoff=2, jitter=(1, 3))
@ -650,9 +655,16 @@ class GithubProvider(GitProvider):
except Exception as e: except Exception as e:
get_logger().exception(f"Failed to publish labels, error: {e}") get_logger().exception(f"Failed to publish labels, error: {e}")
def get_pr_labels(self): def get_pr_labels(self, update=False):
try: try:
return [label.name for label in self.pr.labels] if not update:
labels =self.pr.labels
return [label.name for label in labels]
else: # obtain the latest labels. Maybe they changed while the AI was running
headers, labels = self.pr._requester.requestJsonAndCheck(
"GET", f"{self.pr.issue_url}/labels")
return [label['name'] for label in labels]
except Exception as e: except Exception as e:
get_logger().exception(f"Failed to get labels, error: {e}") get_logger().exception(f"Failed to get labels, error: {e}")
return [] return []
@ -733,22 +745,4 @@ class GithubProvider(GitProvider):
return False return False
def calc_pr_statistics(self, pull_request_data: dict): def calc_pr_statistics(self, pull_request_data: dict):
try: return {}
out = {}
from datetime import datetime
created_at = pull_request_data['created_at']
closed_at = pull_request_data['closed_at']
closed_at_datetime = datetime.strptime(closed_at, "%Y-%m-%dT%H:%M:%SZ")
created_at_datetime = datetime.strptime(created_at, "%Y-%m-%dT%H:%M:%SZ")
difference = closed_at_datetime - created_at_datetime
out['hours'] = difference.total_seconds() / 3600
out['commits'] = pull_request_data['commits']
out['comments'] = pull_request_data['comments']
out['review_comments'] = pull_request_data['review_comments']
out['changed_files'] = pull_request_data['changed_files']
out['additions'] = pull_request_data['additions']
out['deletions'] = pull_request_data['deletions']
except Exception as e:
get_logger().exception(f"Failed to calculate PR statistics, error: {e}")
return {}
return out

View File

@ -419,7 +419,7 @@ class GitLabProvider(GitProvider):
def publish_inline_comments(self, comments: list[dict]): def publish_inline_comments(self, comments: list[dict]):
pass pass
def get_pr_labels(self): def get_pr_labels(self, update=False):
return self.mr.labels return self.mr.labels
def get_repo_labels(self): def get_repo_labels(self):

View File

@ -176,5 +176,5 @@ class LocalGitProvider(GitProvider):
def get_issue_comments(self): def get_issue_comments(self):
raise NotImplementedError('Getting issue comments is not implemented for the local git provider') raise NotImplementedError('Getting issue comments is not implemented for the local git provider')
def get_pr_labels(self): def get_pr_labels(self, update=False):
raise NotImplementedError('Getting labels is not implemented for the local git provider') raise NotImplementedError('Getting labels is not implemented for the local git provider')

View File

View File

@ -46,19 +46,22 @@ async def run_action():
if not GITHUB_EVENT_PATH: if not GITHUB_EVENT_PATH:
print("GITHUB_EVENT_PATH not set") print("GITHUB_EVENT_PATH not set")
return return
if not OPENAI_KEY:
print("OPENAI_KEY not set")
return
if not GITHUB_TOKEN: if not GITHUB_TOKEN:
print("GITHUB_TOKEN not set") print("GITHUB_TOKEN not set")
return return
# Set the environment variables in the settings # Set the environment variables in the settings
get_settings().set("OPENAI.KEY", OPENAI_KEY) if OPENAI_KEY:
get_settings().set("OPENAI.KEY", OPENAI_KEY)
else:
# Might not be set if the user is using models not from OpenAI
print("OPENAI_KEY not set")
if OPENAI_ORG: if OPENAI_ORG:
get_settings().set("OPENAI.ORG", OPENAI_ORG) get_settings().set("OPENAI.ORG", OPENAI_ORG)
get_settings().set("GITHUB.USER_TOKEN", GITHUB_TOKEN) get_settings().set("GITHUB.USER_TOKEN", GITHUB_TOKEN)
get_settings().set("GITHUB.DEPLOYMENT_TYPE", "user") get_settings().set("GITHUB.DEPLOYMENT_TYPE", "user")
enable_output = get_setting_or_env("GITHUB_ACTION_CONFIG.ENABLE_OUTPUT", True)
get_settings().set("GITHUB_ACTION_CONFIG.ENABLE_OUTPUT", enable_output)
# Load the event payload # Load the event payload
try: try:
@ -101,6 +104,8 @@ async def run_action():
await PRReviewer(pr_url).run() await PRReviewer(pr_url).run()
if auto_improve is None or is_true(auto_improve): if auto_improve is None or is_true(auto_improve):
await PRCodeSuggestions(pr_url).run() await PRCodeSuggestions(pr_url).run()
else:
get_logger().info(f"Skipping action: {action}")
# Handle issue comment event # Handle issue comment event
elif GITHUB_EVENT_NAME == "issue_comment" or GITHUB_EVENT_NAME == "pull_request_review_comment": elif GITHUB_EVENT_NAME == "issue_comment" or GITHUB_EVENT_NAME == "pull_request_review_comment":

View File

@ -86,8 +86,13 @@ async def handle_comments_on_pr(body: Dict[str, Any],
return {} return {}
comment_body = body.get("comment", {}).get("body") comment_body = body.get("comment", {}).get("body")
if comment_body and isinstance(comment_body, str) and not comment_body.lstrip().startswith("/"): if comment_body and isinstance(comment_body, str) and not comment_body.lstrip().startswith("/"):
get_logger().info("Ignoring comment not starting with /") if '/ask' in comment_body and comment_body.strip().startswith('> ![image]'):
return {} comment_body_split = comment_body.split('/ask')
comment_body = '/ask' + comment_body_split[1] +' \n' +comment_body_split[0].strip().lstrip('>')
get_logger().info(f"Reformatting comment_body so command is at the beginning: {comment_body}")
else:
get_logger().info("Ignoring comment not starting with /")
return {}
disable_eyes = False disable_eyes = False
if "issue" in body and "pull_request" in body["issue"] and "url" in body["issue"]["pull_request"]: if "issue" in body and "pull_request" in body["issue"] and "url" in body["issue"]["pull_request"]:
api_url = body["issue"]["pull_request"]["url"] api_url = body["issue"]["pull_request"]["url"]
@ -135,7 +140,7 @@ async def handle_new_pr_opened(body: Dict[str, Any],
if not (pull_request and api_url): if not (pull_request and api_url):
get_logger().info(f"Invalid PR event: {action=} {api_url=}") get_logger().info(f"Invalid PR event: {action=} {api_url=}")
return {} return {}
if action in get_settings().github_app.handle_pr_actions: # ['opened', 'reopened', 'ready_for_review', 'review_requested'] if action in get_settings().github_app.handle_pr_actions: # ['opened', 'reopened', 'ready_for_review']
if get_identity_provider().verify_eligibility("github", sender_id, api_url) is not Eligibility.NOT_ELIGIBLE: if get_identity_provider().verify_eligibility("github", sender_id, api_url) is not Eligibility.NOT_ELIGIBLE:
await _perform_auto_commands_github("pr_commands", agent, body, api_url, log_context) await _perform_auto_commands_github("pr_commands", agent, body, api_url, log_context)
else: else:
@ -224,19 +229,22 @@ def handle_closed_pr(body, event, action, log_context):
def get_log_context(body, event, action, build_number): def get_log_context(body, event, action, build_number):
sender = "" sender = ""
sender_id = "" sender_id = ""
sender_type = ""
try: try:
sender = body.get("sender", {}).get("login") sender = body.get("sender", {}).get("login")
sender_id = body.get("sender", {}).get("id") sender_id = body.get("sender", {}).get("id")
sender_type = body.get("sender", {}).get("type")
repo = body.get("repository", {}).get("full_name", "") repo = body.get("repository", {}).get("full_name", "")
git_org = body.get("organization", {}).get("login", "") git_org = body.get("organization", {}).get("login", "")
installation_id = body.get("installation", {}).get("id", "")
app_name = get_settings().get("CONFIG.APP_NAME", "Unknown") app_name = get_settings().get("CONFIG.APP_NAME", "Unknown")
log_context = {"action": action, "event": event, "sender": sender, "server_type": "github_app", log_context = {"action": action, "event": event, "sender": sender, "server_type": "github_app",
"request_id": uuid.uuid4().hex, "build_number": build_number, "app_name": app_name, "request_id": uuid.uuid4().hex, "build_number": build_number, "app_name": app_name,
"repo": repo, "git_org": git_org} "repo": repo, "git_org": git_org, "installation_id": installation_id}
except Exception as e: except Exception as e:
get_logger().error("Failed to get log context", e) get_logger().error("Failed to get log context", e)
log_context = {} log_context = {}
return log_context, sender, sender_id return log_context, sender, sender_id, sender_type
async def handle_request(body: Dict[str, Any], event: str): async def handle_request(body: Dict[str, Any], event: str):
@ -251,7 +259,13 @@ async def handle_request(body: Dict[str, Any], event: str):
if not action: if not action:
return {} return {}
agent = PRAgent() agent = PRAgent()
log_context, sender, sender_id = get_log_context(body, event, action, build_number) log_context, sender, sender_id, sender_type = get_log_context(body, event, action, build_number)
# logic to ignore PRs opened by bot
if get_settings().get("GITHUB_APP.IGNORE_BOT_PR", False) and sender_type == "Bot":
if 'pr-agent' not in sender:
get_logger().info(f"Ignoring PR from '{sender=}' because it is a bot")
return {}
# handle comments on PRs # handle comments on PRs
if action == 'created': if action == 'created':

View File

@ -9,7 +9,7 @@ class HelpMessage:
"> - **/add_docs** 💎: Generate docstring for new components introduced in the PR. \n" \ "> - **/add_docs** 💎: Generate docstring for new components introduced in the PR. \n" \
"> - **/generate_labels** 💎: Generate labels for the PR based on the PR's contents. \n" \ "> - **/generate_labels** 💎: Generate labels for the PR based on the PR's contents. \n" \
"> - **/analyze** 💎: Automatically analyzes the PR, and presents changes walkthrough for each component. \n\n" \ "> - **/analyze** 💎: Automatically analyzes the PR, and presents changes walkthrough for each component. \n\n" \
">See the [tools guide](https://github.com/Codium-ai/pr-agent/blob/main/docs/TOOLS_GUIDE.md) for more details.\n" \ ">See the [tools guide](https://pr-agent-docs.codium.ai/tools/) for more details.\n" \
">To list the possible configuration parameters, add a **/config** comment. \n" ">To list the possible configuration parameters, add a **/config** comment. \n"
return commands_text return commands_text
@ -22,116 +22,22 @@ class HelpMessage:
@staticmethod @staticmethod
def get_review_usage_guide(): def get_review_usage_guide():
output ="**Overview:**\n" output ="**Overview:**\n"
output +="The `review` tool scans the PR code changes, and generates a PR review. The tool can be triggered [automatically](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#github-app-automatic-tools) every time a new PR is opened, or can be invoked manually by commenting on any PR.\n" output +=("The `review` tool scans the PR code changes, and generates a PR review which includes several types of feedbacks, such as possible PR issues, security threats and relevant test in the PR. More feedbacks can be [added](https://pr-agent-docs.codium.ai/tools/review/#general-configurations) by configuring the tool.\n\n"
"The tool can be triggered [automatically](https://pr-agent-docs.codium.ai/usage-guide/automations_and_usage/#github-app-automatic-tools-when-a-new-pr-is-opened) every time a new PR is opened, or can be invoked manually by commenting on any PR.\n")
output +="""\ output +="""\
When commenting, to edit [configurations](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L19) related to the review tool (`pr_reviewer` section), use the following template: - When commenting, to edit [configurations](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L23) related to the review tool (`pr_reviewer` section), use the following template:
``` ```
/review --pr_reviewer.some_config1=... --pr_reviewer.some_config2=... /review --pr_reviewer.some_config1=... --pr_reviewer.some_config2=...
``` ```
With a [configuration file](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#working-with-github-app), use the following template: - With a [configuration file](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/), use the following template:
``` ```
[pr_reviewer] [pr_reviewer]
some_config1=... some_config1=...
some_config2=... some_config2=...
``` ```
""" """
output +="\n\n<table>"
# extra instructions output += f"\n\nSee the review [usage page](https://pr-agent-docs.codium.ai/tools/review/) for a comprehensive guide on using this tool.\n\n"
output += "<tr><td><details> <summary><strong> Utilizing extra instructions</strong></summary><hr>\n\n"
output += '''\
The `review` tool can be configured with extra instructions, which can be used to guide the model to a feedback tailored to the needs of your project.
Be specific, clear, and concise in the instructions. With extra instructions, you are the prompter. Specify the relevant sub-tool, and the relevant aspects of the PR that you want to emphasize.
Examples for extra instructions:
```
[pr_reviewer] # /review #
extra_instructions="""
In the 'possible issues' section, emphasize the following:
- Does the code logic cover relevant edge cases?
- Is the code logic clear and easy to understand?
- Is the code logic efficient?
...
"""
```
Use triple quotes to write multi-line instructions. Use bullet points to make the instructions more readable.
'''
output += "\n\n</details></td></tr>\n\n"
# automation
output += "<tr><td><details> <summary><strong> How to enable\\disable automation</strong></summary><hr>\n\n"
output += """\
- When you first install PR-Agent app, the [default mode](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#github-app-automatic-tools) for the `review` tool is:
```
pr_commands = ["/review", ...]
```
meaning the `review` tool will run automatically on every PR, with the default configuration.
Edit this field to enable/disable the tool, or to change the used configurations
"""
output += "\n\n</details></td></tr>\n\n"
# # code feedback
# output += "<tr><td><details> <summary><strong> About the 'Code feedback' section</strong></summary><hr>\n\n"
# output+="""\
# The `review` tool provides several type of feedbacks, one of them is code suggestions.
# If you are interested **only** in the code suggestions, it is recommended to use the [`improve`](https://github.com/Codium-ai/pr-agent/blob/main/docs/IMPROVE.md) feature instead, since it dedicated only to code suggestions, and usually gives better results.
# Use the `review` tool if you want to get a more comprehensive feedback, which includes code suggestions as well.
# """
# output += "\n\n</details></td></tr>\n\n"
# auto-labels
output += "<tr><td><details> <summary><strong> Auto-labels</strong></summary><hr>\n\n"
output+="""\
The `review` tool can auto-generate two specific types of labels for a PR:
- a `possible security issue` label, that detects possible [security issues](https://github.com/Codium-ai/pr-agent/blob/tr/user_description/pr_agent/settings/pr_reviewer_prompts.toml#L136) (`enable_review_labels_security` flag)
- a `Review effort [1-5]: x` label, where x is the estimated effort to review the PR (`enable_review_labels_effort` flag)
"""
output += "\n\n</details></td></tr>\n\n"
# extra sub-tools
output += "<tr><td><details> <summary><strong> Extra sub-tools</strong></summary><hr>\n\n"
output += """\
The `review` tool provides a collection of possible feedbacks about a PR.
It is recommended to review the [possible options](https://github.com/Codium-ai/pr-agent/blob/main/docs/REVIEW.md#enabledisable-features), and choose the ones relevant for your use case.
Some of the feature that are disabled by default are quite useful, and should be considered for enabling. For example:
`require_score_review`, `require_soc2_ticket`, and more.
"""
output += "\n\n</details></td></tr>\n\n"
output += "<tr><td><details> <summary><strong> Auto-approve PRs</strong></summary><hr>\n\n"
output += '''\
By invoking:
```
/review auto_approve
```
The tool will automatically approve the PR, and add a comment with the approval.
To ensure safety, the auto-approval feature is disabled by default. To enable auto-approval, you need to actively set in a pre-defined configuration file the following:
```
[pr_reviewer]
enable_auto_approval = true
```
(this specific flag cannot be set with a command line argument, only in the configuration file, committed to the repository)
You can also enable auto-approval only if the PR meets certain requirements, such as that the `estimated_review_effort` is equal or below a certain threshold, by adjusting the flag:
```
[pr_reviewer]
maximal_review_effort = 5
```
'''
output += "\n\n</details></td></tr>\n\n"
# general
output += "\n\n<tr><td><details> <summary><strong> More PR-Agent commands</strong></summary><hr> \n\n"
output += HelpMessage.get_general_bot_help_text()
output += "\n\n</details></td></tr>\n\n"
output += "</table>"
output += f"\n\nSee the [review usage](https://github.com/Codium-ai/pr-agent/blob/main/docs/REVIEW.md) page for a comprehensive guide on using this tool.\n\n"
return output return output
@ -141,14 +47,14 @@ maximal_review_effort = 5
def get_describe_usage_guide(): def get_describe_usage_guide():
output = "**Overview:**\n" output = "**Overview:**\n"
output += "The `describe` tool scans the PR code changes, and generates a description for the PR - title, type, summary, walkthrough and labels. " output += "The `describe` tool scans the PR code changes, and generates a description for the PR - title, type, summary, walkthrough and labels. "
output += "The tool can be triggered [automatically](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#github-app-automatic-tools) every time a new PR is opened, or can be invoked manually by commenting on a PR.\n" output += "The tool can be triggered [automatically](https://pr-agent-docs.codium.ai/usage-guide/automations_and_usage/#github-app-automatic-tools-when-a-new-pr-is-opened) every time a new PR is opened, or can be invoked manually by commenting on a PR.\n"
output += """\ output += """\
When commenting, to edit [configurations](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L46) related to the describe tool (`pr_description` section), use the following template: When commenting, to edit [configurations](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L46) related to the describe tool (`pr_description` section), use the following template:
``` ```
/describe --pr_description.some_config1=... --pr_description.some_config2=... /describe --pr_description.some_config1=... --pr_description.some_config2=...
``` ```
With a [configuration file](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#working-with-github-app), use the following template: With a [configuration file](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/), use the following template:
``` ```
[pr_description] [pr_description]
some_config1=... some_config1=...
@ -160,12 +66,11 @@ some_config2=...
# automation # automation
output += "<tr><td><details> <summary><strong> Enabling\\disabling automation </strong></summary><hr>\n\n" output += "<tr><td><details> <summary><strong> Enabling\\disabling automation </strong></summary><hr>\n\n"
output += """\ output += """\
- When you first install the app, the [default mode](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#github-app-automatic-tools) for the describe tool is: - When you first install the app, the [default mode](https://pr-agent-docs.codium.ai/usage-guide/automations_and_usage/#github-app-automatic-tools-when-a-new-pr-is-opened) for the describe tool is:
``` ```
pr_commands = ["/describe --pr_description.add_original_user_description=true" pr_commands = ["/describe", ...]
"--pr_description.keep_original_user_title=true", ...]
``` ```
meaning the `describe` tool will run automatically on every PR, will keep the original title, and will add the original user description above the generated description. meaning the `describe` tool will run automatically on every PR.
- Markers are an alternative way to control the generated description, to give maximal control to the user. If you set: - Markers are an alternative way to control the generated description, to give maximal control to the user. If you set:
``` ```
@ -186,7 +91,7 @@ Note that when markers are enabled, if the original PR description does not cont
output += """\ output += """\
The default labels of the `describe` tool are quite generic: [`Bug fix`, `Tests`, `Enhancement`, `Documentation`, `Other`]. The default labels of the `describe` tool are quite generic: [`Bug fix`, `Tests`, `Enhancement`, `Documentation`, `Other`].
If you specify [custom labels](https://github.com/Codium-ai/pr-agent/blob/main/docs/DESCRIBE.md#handle-custom-labels-from-the-repos-labels-page-gem) in the repo's labels page or via configuration file, you can get tailored labels for your use cases. If you specify [custom labels](https://pr-agent-docs.codium.ai/tools/describe/#handle-custom-labels-from-the-repos-labels-page) in the repo's labels page or via configuration file, you can get tailored labels for your use cases.
Examples for custom labels: Examples for custom labels:
- `Main topic:performance` - pr_agent:The main topic of this PR is performance - `Main topic:performance` - pr_agent:The main topic of this PR is performance
- `New endpoint` - pr_agent:A new endpoint was added in this PR - `New endpoint` - pr_agent:A new endpoint was added in this PR
@ -222,7 +127,7 @@ Be specific, clear, and concise in the instructions. With extra instructions, yo
Examples for extra instructions: Examples for extra instructions:
``` ```
[pr_description] [pr_description]
extra_instructions=""" extra_instructions="""\
- The PR title should be in the format: '<PR type>: <title>' - The PR title should be in the format: '<PR type>: <title>'
- The title should be short and concise (up to 10 words) - The title should be short and concise (up to 10 words)
- ... - ...
@ -240,7 +145,7 @@ Use triple quotes to write multi-line instructions. Use bullet points to make th
output += "</table>" output += "</table>"
output += f"\n\nSee the [describe usage](https://github.com/Codium-ai/pr-agent/blob/main/docs/DESCRIBE.md) page for a comprehensive guide on using this tool.\n\n" output += f"\n\nSee the [describe usage](https://pr-agent-docs.codium.ai/tools/describe/) page for a comprehensive guide on using this tool.\n\n"
return output return output
@ -254,18 +159,19 @@ It can be invoked manually by commenting on any PR:
/ask "..." /ask "..."
``` ```
Note that the tool does not have "memory" of previous questions, and answers each question independently. Note that the tool does not have "memory" of previous questions, and answers each question independently.
You can ask questions about the entire PR, about specific code lines, or about an image related to the PR code changes.
""" """
output += "\n\n<table>" # output += "\n\n<table>"
#
# # # general
# # output += "\n\n<tr><td><details> <summary><strong> More PR-Agent commands</strong></summary><hr> \n\n"
# # output += HelpMessage.get_general_bot_help_text()
# # output += "\n\n</details></td></tr>\n\n"
#
# output += "</table>"
# general output += f"\n\nSee the [ask usage](https://pr-agent-docs.codium.ai/tools/ask/) page for a comprehensive guide on using this tool.\n\n"
output += "\n\n<tr><td><details> <summary><strong> More PR-Agent commands</strong></summary><hr> \n\n"
output += HelpMessage.get_general_bot_help_text()
output += "\n\n</details></td></tr>\n\n"
output += "</table>"
output += f"\n\nSee the [ask usage](https://github.com/Codium-ai/pr-agent/blob/main/docs/ASK.md) page for a comprehensive guide on using this tool.\n\n"
return output return output
@ -273,16 +179,16 @@ Note that the tool does not have "memory" of previous questions, and answers eac
@staticmethod @staticmethod
def get_improve_usage_guide(): def get_improve_usage_guide():
output = "**Overview:**\n" output = "**Overview:**\n"
output += "The `improve` tool scans the PR code changes, and automatically generates suggestions for improving the PR code. " output += "The code suggestions tool, named `improve`, scans the PR code changes, and automatically generates code suggestions for improving the PR."
output += "The tool can be triggered [automatically](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#github-app-automatic-tools) every time a new PR is opened, or can be invoked manually by commenting on a PR.\n" output += "The tool can be triggered [automatically](https://pr-agent-docs.codium.ai/usage-guide/automations_and_usage/#github-app-automatic-tools-when-a-new-pr-is-opened) every time a new PR is opened, or can be invoked manually by commenting on a PR.\n"
output += """\ output += """\
When commenting, to edit [configurations](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L69) related to the improve tool (`pr_code_suggestions` section), use the following template: - When commenting, to edit [configurations](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L78) related to the improve tool (`pr_code_suggestions` section), use the following template:
``` ```
/improve --pr_code_suggestions.some_config1=... --pr_code_suggestions.some_config2=... /improve --pr_code_suggestions.some_config1=... --pr_code_suggestions.some_config2=...
``` ```
With a [configuration file](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#working-with-github-app), use the following template: - With a [configuration file](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/), use the following template:
``` ```
[pr_code_suggestions] [pr_code_suggestions]
@ -291,64 +197,7 @@ some_config2=...
``` ```
""" """
output += "\n\n<table>"
# automation output += f"\n\nSee the improve [usage page](https://pr-agent-docs.codium.ai/tools/improve/) for a comprehensive guide on using this tool.\n\n"
output += "<tr><td><details> <summary><strong> Enabling\\disabling automation </strong></summary><hr>\n\n"
output += """\
When you first install the app, the [default mode](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#github-app-automatic-tools) for the improve tool is:
```
pr_commands = ["/improve --pr_code_suggestions.summarize=true", ...]
```
meaning the `improve` tool will run automatically on every PR, with summarization enabled. Delete this line to disable the tool from running automatically.
"""
output += "\n\n</details></td></tr>\n\n"
# extra instructions
output += "<tr><td><details> <summary><strong> Utilizing extra instructions</strong></summary><hr>\n\n"
output += '''\
Extra instructions are very important for the `improve` tool, since they enable to guide the model to suggestions that are more relevant to the specific needs of the project.
Be specific, clear, and concise in the instructions. With extra instructions, you are the prompter. Specify relevant aspects that you want the model to focus on.
Examples for extra instructions:
```
[pr_code_suggestions] # /improve #
extra_instructions="""
Emphasize the following aspects:
- Does the code logic cover relevant edge cases?
- Is the code logic clear and easy to understand?
- Is the code logic efficient?
...
"""
```
Use triple quotes to write multi-line instructions. Use bullet points to make the instructions more readable.
'''
output += "\n\n</details></td></tr>\n\n"
# suggestions quality
output += "\n\n<tr><td><details> <summary><strong> A note on code suggestions quality</strong></summary><hr> \n\n"
output += """\
- While the current AI for code is getting better and better (GPT-4), it's not flawless. Not all the suggestions will be perfect, and a user should not accept all of them automatically.
- Suggestions are not meant to be simplistic. Instead, they aim to give deep feedback and raise questions, ideas and thoughts to the user, who can then use his judgment, experience, and understanding of the code base.
- Recommended to use the 'extra_instructions' field to guide the model to suggestions that are more relevant to the specific needs of the project, or use the [custom suggestions :gem:](https://github.com/Codium-ai/pr-agent/blob/main/docs/CUSTOM_SUGGESTIONS.md) tool
- With large PRs, best quality will be obtained by using 'improve --extended' mode.
"""
output += "\n\n</details></td></tr>\n\n"\
# general
output += "\n\n<tr><td><details> <summary><strong> More PR-Agent commands</strong></summary><hr> \n\n"
output += HelpMessage.get_general_bot_help_text()
output += "\n\n</details></td></tr>\n\n"
output += "</table>"
output += f"\n\nSee the [improve usage](https://github.com/Codium-ai/pr-agent/blob/main/docs/IMPROVE.md) page for a more comprehensive guide on using this tool.\n\n"
return output return output

View File

@ -29,6 +29,9 @@ key = "" # Optional, uncomment if you want to use Cohere. Acquire through https:
[replicate] [replicate]
key = "" # Optional, uncomment if you want to use Replicate. Acquire through https://replicate.com/ key = "" # Optional, uncomment if you want to use Replicate. Acquire through https://replicate.com/
[groq]
key = "" # Acquire through https://console.groq.com/keys
[huggingface] [huggingface]
key = "" # Optional, uncomment if you want to use Huggingface Inference API. Acquire through https://huggingface.co/docs/api-inference/quicktour key = "" # Optional, uncomment if you want to use Huggingface Inference API. Acquire through https://huggingface.co/docs/api-inference/quicktour
api_base = "" # the base url for your huggingface inference endpoint api_base = "" # the base url for your huggingface inference endpoint

View File

@ -1,7 +1,7 @@
[config] [config]
model="gpt-4" # "gpt-4-0125-preview" model="gpt-4-turbo-2024-04-09"
model_turbo="gpt-4-0125-preview" model_turbo="gpt-4o"
fallback_models=["gpt-3.5-turbo-16k"] fallback_models=["gpt-4-0125-preview"]
git_provider="github" git_provider="github"
publish_output=true publish_output=true
publish_output_progress=true publish_output_progress=true
@ -19,13 +19,14 @@ secret_provider="google_cloud_storage"
cli_mode=false cli_mode=false
ai_disclaimer_title="" # Pro feature, title for a collapsible disclaimer to AI outputs ai_disclaimer_title="" # Pro feature, title for a collapsible disclaimer to AI outputs
ai_disclaimer="" # Pro feature, full text for the AI disclaimer ai_disclaimer="" # Pro feature, full text for the AI disclaimer
output_relevant_configurations=false
[pr_reviewer] # /review # [pr_reviewer] # /review #
# enable/disable features # enable/disable features
require_focused_review=false
require_score_review=false require_score_review=false
require_tests_review=true require_tests_review=true
require_estimate_effort_to_review=true require_estimate_effort_to_review=true
require_can_be_split_review=false
# soc2 # soc2
require_soc2_ticket=false require_soc2_ticket=false
soc2_ticket_prompt="Does the PR description include a link to ticket in a project management system (e.g., Jira, Asana, Trello, etc.) ?" soc2_ticket_prompt="Does the PR description include a link to ticket in a project management system (e.g., Jira, Asana, Trello, etc.) ?"
@ -44,7 +45,7 @@ enable_review_labels_effort=true
require_all_thresholds_for_incremental_review=false require_all_thresholds_for_incremental_review=false
minimal_commits_for_incremental_review=0 minimal_commits_for_incremental_review=0
minimal_minutes_for_incremental_review=0 minimal_minutes_for_incremental_review=0
enable_help_text=true # Determines whether to include help text in the PR review. Enabled by default. enable_help_text=false # Determines whether to include help text in the PR review. Enabled by default.
# auto approval # auto approval
enable_auto_approval=false enable_auto_approval=false
maximal_review_effort=5 maximal_review_effort=5
@ -52,15 +53,17 @@ maximal_review_effort=5
[pr_description] # /describe # [pr_description] # /describe #
publish_labels=true publish_labels=true
publish_description_as_comment=false
add_original_user_description=true add_original_user_description=true
keep_original_user_title=true generate_ai_title=false
use_bullet_points=true use_bullet_points=true
extra_instructions = "" extra_instructions = ""
enable_pr_type=true enable_pr_type=true
final_update_message = true final_update_message = true
enable_help_text=false enable_help_text=false
enable_help_comment=true enable_help_comment=true
# describe as comment
publish_description_as_comment=false
publish_description_as_comment_persistent=true
## changes walkthrough section ## changes walkthrough section
enable_semantic_files_types=true enable_semantic_files_types=true
collapsible_file_list='adaptive' # true, false, 'adaptive' collapsible_file_list='adaptive' # true, false, 'adaptive'
@ -72,19 +75,23 @@ include_generated_by_header=true
#custom_labels = ['Bug fix', 'Tests', 'Bug fix with tests', 'Enhancement', 'Documentation', 'Other'] #custom_labels = ['Bug fix', 'Tests', 'Bug fix with tests', 'Enhancement', 'Documentation', 'Other']
[pr_questions] # /ask # [pr_questions] # /ask #
enable_help_text=true enable_help_text=false
[pr_code_suggestions] # /improve # [pr_code_suggestions] # /improve #
max_context_tokens=8000 max_context_tokens=8000
num_code_suggestions=4 num_code_suggestions=4
summarize = true commitable_code_suggestions = false
extra_instructions = "" extra_instructions = ""
rank_suggestions = false rank_suggestions = false
enable_help_text=true enable_help_text=false
persistent_comment=false
# suggestions scoring
self_reflect_on_suggestions=true
suggestions_score_threshold=0 # [0-10]. highly recommend not to set this value above 8, since above it may clip highly relevant suggestions
# params for '/improve --extended' mode # params for '/improve --extended' mode
auto_extended_mode=true auto_extended_mode=true
num_code_suggestions_per_chunk=5 num_code_suggestions_per_chunk=4
max_number_of_calls = 3 max_number_of_calls = 3
parallel_calls = true parallel_calls = true
rank_extended_suggestions = false rank_extended_suggestions = false
@ -107,8 +114,13 @@ num_tests=3 # number of tests to generate. max 5.
avoid_mocks=true # if true, the generated tests will prefer to use real objects instead of mocks avoid_mocks=true # if true, the generated tests will prefer to use real objects instead of mocks
file = "" # in case there are several components with the same name, you can specify the relevant file file = "" # in case there are several components with the same name, you can specify the relevant file
class_name = "" # in case there are several methods with the same name in the same file, you can specify the relevant class name class_name = "" # in case there are several methods with the same name in the same file, you can specify the relevant class name
enable_help_text=true enable_help_text=false
[pr_improve_component] # /improve_component #
num_code_suggestions=4
extra_instructions = ""
file = "" # in case there are several components with the same name, you can specify the relevant file
class_name = ""
[checks] # /checks (pro feature) # [checks] # /checks (pro feature) #
enable_auto_checks_feedback=true enable_auto_checks_feedback=true
@ -132,6 +144,7 @@ try_fix_invalid_inline_comments = true
# auto_review = true # set as env var in .github/workflows/pr-agent.yaml # auto_review = true # set as env var in .github/workflows/pr-agent.yaml
# auto_describe = true # set as env var in .github/workflows/pr-agent.yaml # auto_describe = true # set as env var in .github/workflows/pr-agent.yaml
# auto_improve = true # set as env var in .github/workflows/pr-agent.yaml # auto_improve = true # set as env var in .github/workflows/pr-agent.yaml
# enable_output = true # set as env var in .github/workflows/pr-agent.yaml
[github_app] [github_app]
# these toggles allows running the github app from custom deployments # these toggles allows running the github app from custom deployments
@ -139,9 +152,9 @@ override_deployment_type = true
# settings for "pull_request" event # settings for "pull_request" event
handle_pr_actions = ['opened', 'reopened', 'ready_for_review'] handle_pr_actions = ['opened', 'reopened', 'ready_for_review']
pr_commands = [ pr_commands = [
"/describe --pr_description.add_original_user_description=true --pr_description.keep_original_user_title=true", "/describe",
"/review --pr_reviewer.num_code_suggestions=0", "/review --pr_reviewer.num_code_suggestions=0",
"/improve --pr_code_suggestions.summarize=true", "/improve",
] ]
# settings for "pull_request" event with "synchronize" action - used to detect and handle push triggers for new commits # settings for "pull_request" event with "synchronize" action - used to detect and handle push triggers for new commits
handle_push_trigger = false handle_push_trigger = false
@ -151,23 +164,24 @@ push_trigger_wait_for_initial_review = true
push_trigger_pending_tasks_backlog = true push_trigger_pending_tasks_backlog = true
push_trigger_pending_tasks_ttl = 300 push_trigger_pending_tasks_ttl = 300
push_commands = [ push_commands = [
"/describe --pr_description.add_original_user_description=true --pr_description.keep_original_user_title=true", "/describe",
"/review --pr_reviewer.num_code_suggestions=0", "/review --pr_reviewer.num_code_suggestions=0",
] ]
ignore_pr_title = [] ignore_pr_title = []
ignore_bot_pr = true
[gitlab] [gitlab]
url = "https://gitlab.com" # URL to the gitlab service url = "https://gitlab.com" # URL to the gitlab service
pr_commands = [ pr_commands = [
"/describe --pr_description.add_original_user_description=true --pr_description.keep_original_user_title=true", "/describe",
"/review --pr_reviewer.num_code_suggestions=0", "/review --pr_reviewer.num_code_suggestions=0",
"/improve --pr_code_suggestions.summarize=true", "/improve",
] ]
[bitbucket_app] [bitbucket_app]
pr_commands = [ pr_commands = [
"/review --pr_reviewer.num_code_suggestions=0", "/review --pr_reviewer.num_code_suggestions=0",
"/improve --pr_code_suggestions.summarize=false", "/improve --pr_code_suggestions.commitable_code_suggestions=true",
] ]
@ -192,7 +206,8 @@ pr_commands = [
url = "" url = ""
[litellm] [litellm]
#use_client = false # use_client = false
# drop_params = false
[pr_similar_issue] [pr_similar_issue]
skip_comments = false skip_comments = false

View File

@ -1,8 +1,9 @@
[pr_code_suggestions_prompt] [pr_code_suggestions_prompt]
system="""You are PR-Reviewer, a language model that specializes in suggesting code improvements for a Pull Request (PR). system="""You are PR-Reviewer, a language model that specializes in suggesting ways to improve for a Pull Request (PR) code.
Your task is to provide meaningful and actionable code suggestions, to improve the new code presented in a PR diff (lines starting with '+'). Your task is to provide meaningful and actionable code suggestions, to improve the new code presented in a PR diff.
Example for the PR Diff format:
The format we will use to present the PR code diff:
====== ======
## file: 'src/file1.py' ## file: 'src/file1.py'
@ -26,22 +27,26 @@ __old hunk__
## file: 'src/file2.py' ## file: 'src/file2.py'
... ...
====== ======
- In this format, we separated each hunk of code to '__new hunk__' and '__old hunk__' sections. The '__new hunk__' section contains the new code of the chunk, and the '__old hunk__' section contains the old code that was removed.
- Code lines are prefixed symbols ('+', '-', ' '). The '+' symbol indicates new code added in the PR, the '-' symbol indicates code removed in the PR, and the ' ' symbol indicates unchanged code.
- We also added line numbers for the '__new hunk__' sections, to help you refer to the code lines in your suggestions. These line numbers are not part of the actual code, and are only used for reference.
Specific instructions: Specific instructions for generating code suggestions:
- Provide up to {{ num_code_suggestions }} code suggestions. The suggestions should be diverse and insightful. - Provide up to {{ num_code_suggestions }} code suggestions. The suggestions should be diverse and insightful.
- The suggestions should refer only to code from the '__new hunk__' sections, and focus on new lines of code (lines starting with '+'). - The suggestions should focus on ways to improve the new code in the PR, meaning focusing on lines from '__new hunk__' sections, starting with '+'. Use the '__old hunk__' sections to understand the context of the code changes.
- Prioritize suggestions that address major problems, issues and bugs in the PR code. As a second priority, suggestions should focus on enhancement, best practice, performance, maintainability, and other aspects. - Prioritize suggestions that address possible issues, major problems, and bugs in the PR code.
- Don't suggest to add docstring, type hints, or comments, or to remove unused imports. - Don't suggest to add docstring, type hints, or comments, or to remove unused imports.
- Suggestions should not repeat code already present in the '__new hunk__' sections. - Suggestions should not repeat code already present in the '__new hunk__' sections.
- Provide the exact line numbers range (inclusive) for each suggestion. - Provide the exact line numbers range (inclusive) for each suggestion. Use the line numbers from the '__new hunk__' sections.
- When quoting variables or names from the code, use backticks (`) instead of single quote ('). - When quoting variables or names from the code, use backticks (`) instead of single quote (').
- Take into account that you are reviewing a PR code diff, and that the entire codebase is not available for you as context. Hence, avoid suggestions that might conflict with unseen parts of the codebase.
{%- if extra_instructions %} {%- if extra_instructions %}
Extra instructions from the user: Extra instructions from the user, that should be taken into account with high priority:
====== ======
{{ extra_instructions }} {{ extra_instructions }}
====== ======
@ -54,17 +59,12 @@ class CodeSuggestion(BaseModel):
relevant_file: str = Field(description="the relevant file full path") relevant_file: str = Field(description="the relevant file full path")
language: str = Field(description="the code language of the relevant file") language: str = Field(description="the code language of the relevant file")
suggestion_content: str = Field(description="an actionable suggestion for meaningfully improving the new code introduced in the PR") suggestion_content: str = Field(description="an actionable suggestion for meaningfully improving the new code introduced in the PR")
{%- if summarize_mode %} existing_code: str = Field(description="a short code snippet, demonstrating the relevant code lines from a '__new hunk__' section. It must be without line numbers. Use abbreviations if needed")
existing_code: str = Field(description="a short code snippet from a '__new hunk__' section to illustrate the relevant existing code. Don't show the line numbers.") improved_code: str = Field(description="a new code snippet, that can be used to replace the relevant 'existing_code' lines in '__new hunk__' code after applying the suggestion")
improved_code: str = Field(description="a short code snippet to illustrate the improved code, after applying the suggestion.") one_sentence_summary: str = Field(description="a short summary of the suggestion action, in a single sentence. Focus on the 'what'. Be general, and avoid method or variable names.")
one_sentence_summary:str = Field(description="a short summary of the suggestion action, in a single sentence. Focus on the 'what'. Be general, and avoid method or variable names.")
{%- else %}
existing_code: str = Field(description="a code snippet, demonstrating the relevant code lines from a '__new hunk__' section. It must be contiguous, correctly formatted and indented, and without line numbers")
improved_code: str = Field(description="a new code snippet, that can be used to replace the relevant lines in '__new hunk__' code. Replacement suggestions should be complete, correctly formatted and indented, and without line numbers")
{%- endif %}
relevant_lines_start: int = Field(description="The relevant line number, from a '__new hunk__' section, where the suggestion starts (inclusive). Should be derived from the hunk line numbers, and correspond to the 'existing code' snippet above") relevant_lines_start: int = Field(description="The relevant line number, from a '__new hunk__' section, where the suggestion starts (inclusive). Should be derived from the hunk line numbers, and correspond to the 'existing code' snippet above")
relevant_lines_end: int = Field(description="The relevant line number, from a '__new hunk__' section, where the suggestion ends (inclusive). Should be derived from the hunk line numbers, and correspond to the 'existing code' snippet above") relevant_lines_end: int = Field(description="The relevant line number, from a '__new hunk__' section, where the suggestion ends (inclusive). Should be derived from the hunk line numbers, and correspond to the 'existing code' snippet above")
label: str = Field(description="a single label for the suggestion, to help the user understand the suggestion type. For example: 'security', 'bug', 'performance', 'enhancement', 'possible issue', 'best practice', 'maintainability', etc. Other labels are also allowed") label: str = Field(description="a single label for the suggestion, to help the user understand the suggestion type. For example: 'security', 'possible bug', 'possible issue', 'performance', 'enhancement', 'best practice', 'maintainability', etc. Other labels are also allowed")
class PRCodeSuggestions(BaseModel): class PRCodeSuggestions(BaseModel):
code_suggestions: List[CodeSuggestion] code_suggestions: List[CodeSuggestion]
@ -80,7 +80,6 @@ code_suggestions:
python python
suggestion_content: | suggestion_content: |
... ...
{%- if summarize_mode %}
existing_code: | existing_code: |
... ...
improved_code: | improved_code: |
@ -89,14 +88,6 @@ code_suggestions:
... ...
relevant_lines_start: 12 relevant_lines_start: 12
relevant_lines_end: 13 relevant_lines_end: 13
{%- else %}
existing_code: |
...
relevant_lines_start: 12
relevant_lines_end: 13
improved_code: |
...
{%- endif %}
label: | label: |
... ...
``` ```

View File

@ -0,0 +1,88 @@
[pr_code_suggestions_reflect_prompt]
system="""You are a language model that specializes in reviewing and evaluating suggestions for a Pull Request (PR) code.
Your input is a PR code, and a list of code suggestions that were generated for the PR.
Your goal is to inspect, review and score the suggestsions.
Be aware - the suggestions may not always be correct or accurate, and you should evaluate them in relation to the actual PR code diff presented. Sometimes the suggestion may ignore parts of the actual code diff, and in that case, you should give it a score of 0.
Specific instructions:
- Carefully review both the suggestion content, and the related PR code diff. Mistakes in the suggestions can occur. Make sure the suggestions are correct, and properly derived from the PR code diff.
- In addition to the exact code lines mentioned in each suggestion, review the code around them, to ensure that the suggestions are contextually accurate.
- Also check that the 'existing_code' and 'improved_code' fields correctly reflect the suggested changes.
- Make sure the suggestions focus on new code introduced in the PR, and not on existing code that was not changed.
- High scores (8 to 10) should be given to correct suggestions that address major bugs and issues, or security concerns. Lower scores (3 to 7) should be for correct suggestions addressing minor issues, code style, code readability, maintainability, etc. Don't give high scores to suggestions that are not crucial, and bring only small improvement or optimization.
- Order the feedback the same way the suggestions are ordered in the input.
The format that is used to present the PR code diff is as follows:
======
## file: 'src/file1.py'
@@ ... @@ def func1():
__new hunk__
12 code line1 that remained unchanged in the PR
13 +new hunk code line2 added in the PR
14 code line3 that remained unchanged in the PR
__old hunk__
code line1 that remained unchanged in the PR
-old hunk code line2 that was removed in the PR
code line3 that remained unchanged in the PR
@@ ... @@ def func2():
__new hunk__
...
__old hunk__
...
## file: 'src/file2.py'
...
======
- In this format, we separated each hunk of code to '__new hunk__' and '__old hunk__' sections. The '__new hunk__' section contains the new code of the chunk, and the '__old hunk__' section contains the old code that was removed.
- Code lines are prefixed symbols ('+', '-', ' '). The '+' symbol indicates new code added in the PR, the '-' symbol indicates code removed in the PR, and the ' ' symbol indicates unchanged code.
- We also added line numbers for the '__new hunk__' sections, to help you refer to the code lines in your suggestions. These line numbers are not part of the actual code, and are only used for reference.
The output must be a YAML object equivalent to type $PRCodeSuggestionsFeedback, according to the following Pydantic definitions:
=====
class CodeSuggestionFeedback(BaseModel):
suggestion_summary: str = Field(description="repeated from the input")
relevant_file: str = Field(description="repeated from the input")
suggestion_score: int = Field(description="The actual output - the score of the suggestion, from 0 to 10. Give 0 if the suggestion is plain wrong. Otherwise, give a score from 1 to 10 (inclusive), where 1 is the lowest and 10 is the highest.")
why: str = Field(description="Short and concise explanation of why the suggestion received the score (one to two sentences).")
class PRCodeSuggestionsFeedback(BaseModel):
code_suggestions: List[CodeSuggestionFeedback]
=====
Example output:
```yaml
code_suggestions:
- suggestion_content: |
Use a more descriptive variable name here
relevant_file: "src/file1.py"
suggestion_score: 6
why: |
The variable name 't' is not descriptive enough
```
Each YAML output MUST be after a newline, indented, with block scalar indicator ('|').
"""
user="""You are given a Pull Request (PR) code diff:
======
{{ diff|trim }}
======
And here is a list of corresponding {{ num_code_suggestions }} code suggestions to improve this Pull Request code:
======
{{ suggestion_str|trim }}
======
Response (should be a valid YAML, and nothing else):
```yaml
"""

View File

@ -49,6 +49,12 @@ Extra instructions from the user:
The output must be a YAML object equivalent to type $PRReview, according to the following Pydantic definitions: The output must be a YAML object equivalent to type $PRReview, according to the following Pydantic definitions:
===== =====
{%- if require_can_be_split_review %}
class SubPR(BaseModel):
relevant_files: List[str] = Field(description="The relevant files of the sub-PR")
title: str = Field(description="Short and concise title for an independent and meaningful sub-PR, composed only from the relevant files")
{%- endif %}
class Review(BaseModel): class Review(BaseModel):
{%- if require_estimate_effort_to_review %} {%- if require_estimate_effort_to_review %}
estimated_effort_to_review_[1-5]: str = Field(description="Estimate, on a scale of 1-5 (inclusive), the time and effort required to review this PR by an experienced and knowledgeable developer. 1 means short and easy review , 5 means long and hard review. Take into account the size, complexity, quality, and the needed changes of the PR code diff. Explain your answer in a short and concise manner.") estimated_effort_to_review_[1-5]: str = Field(description="Estimate, on a scale of 1-5 (inclusive), the time and effort required to review this PR by an experienced and knowledgeable developer. 1 means short and easy review , 5 means long and hard review. Take into account the size, complexity, quality, and the needed changes of the PR code diff. Explain your answer in a short and concise manner.")
@ -61,12 +67,12 @@ class Review(BaseModel):
{%- endif %} {%- endif %}
{%- if question_str %} {%- if question_str %}
insights_from_user_answers: str = Field(description="shortly summarize the insights you gained from the user's answers to the questions") insights_from_user_answers: str = Field(description="shortly summarize the insights you gained from the user's answers to the questions")
{%- endif %}
{%- if require_focused %}
focused_pr: str = Field(description="Is this a focused PR, in the sense that all the PR code diff changes are united under a single focused theme ? If the theme is too broad, or the PR code diff changes are too scattered, then the PR is not focused. Explain your answer shortly.")
{%- endif %} {%- endif %}
possible_issues: str = Field(description="Does this PR code introduce clear issues, bugs, or major performance concerns? If there are no apparent issues, respond with 'No'. If there are any issues, describe them briefly. Use bullet points if more than one issue. Be specific, and provide examples if possible. Start each bullet point with a short specific header, such as: "- Possible Bug: ...", etc.") possible_issues: str = Field(description="Does this PR code introduce clear issues, bugs, or major performance concerns? If there are no apparent issues, respond with 'No'. If there are any issues, describe them briefly. Use bullet points if more than one issue. Be specific, and provide examples if possible. Start each bullet point with a short specific header, such as: "- Possible Bug: ...", etc.")
security_concerns: str = Field(description="does this PR code introduce possible vulnerabilities such as exposure of sensitive information (e.g., API keys, secrets, passwords), or security concerns like SQL injection, XSS, CSRF, and others ? Answer 'No' if there are no possible issues. If there are security concerns or issues, start your answer with a short header, such as: 'Sensitive information exposure: ...', 'SQL injection: ...' etc. Explain your answer. Be specific and give examples if possible") security_concerns: str = Field(description="does this PR code introduce possible vulnerabilities such as exposure of sensitive information (e.g., API keys, secrets, passwords), or security concerns like SQL injection, XSS, CSRF, and others ? Answer 'No' if there are no possible issues. If there are security concerns or issues, start your answer with a short header, such as: 'Sensitive information exposure: ...', 'SQL injection: ...' etc. Explain your answer. Be specific and give examples if possible")
{%- if require_can_be_split_review %}
can_be_split: List[SubPR] = Field(min_items=0, max_items=3, description="Can this PR, which contains {{ num_pr_files }} changed files in total, be divided into smaller sub-PRs with distinct tasks that can be reviewed and merged independently, regardless of the order ? Make sure that the sub-PRs are indeed independent, with no code dependencies between them, and that each sub-PR represent a meaningfull independent task. Output an empty list if the PR code does not needd to be split.")
{%- endif %}
{%- if num_code_suggestions > 0 %} {%- if num_code_suggestions > 0 %}
class CodeSuggestion(BaseModel): class CodeSuggestion(BaseModel):
@ -100,14 +106,18 @@ review:
{%- endif %} {%- endif %}
relevant_tests: | relevant_tests: |
No No
{%- if require_focused %}
focused_pr: |
no, because ...
{%- endif %}
possible_issues: | possible_issues: |
No No
security_concerns: | security_concerns: |
No No
{%- if require_can_be_split_review %}
can_be_split: |
- relevant_files:
- ...
- ...
title: ...
- ...
{%- endif %}
{%- if num_code_suggestions > 0 %} {%- if num_code_suggestions > 0 %}
code_feedback code_feedback
- relevant_file: | - relevant_file: |

View File

@ -26,6 +26,8 @@ class PRAddDocs:
) )
self.ai_handler = ai_handler() self.ai_handler = ai_handler()
self.ai_handler.main_pr_language = self.main_language
self.patches_diff = None self.patches_diff = None
self.prediction = None self.prediction = None
self.cli_mode = cli_mode self.cli_mode = cli_mode

View File

@ -9,7 +9,7 @@ from pr_agent.algo.ai_handlers.base_ai_handler import BaseAiHandler
from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler
from pr_agent.algo.pr_processing import get_pr_diff, get_pr_multi_diffs, retry_with_fallback_models from pr_agent.algo.pr_processing import get_pr_diff, get_pr_multi_diffs, retry_with_fallback_models
from pr_agent.algo.token_handler import TokenHandler from pr_agent.algo.token_handler import TokenHandler
from pr_agent.algo.utils import load_yaml, replace_code_tags, ModelType from pr_agent.algo.utils import load_yaml, replace_code_tags, ModelType, show_relevant_configurations
from pr_agent.config_loader import get_settings from pr_agent.config_loader import get_settings
from pr_agent.git_providers import get_git_provider from pr_agent.git_providers import get_git_provider
from pr_agent.git_providers.git_provider import get_main_pr_language from pr_agent.git_providers.git_provider import get_main_pr_language
@ -46,6 +46,7 @@ class PRCodeSuggestions:
num_code_suggestions = get_settings().pr_code_suggestions.num_code_suggestions num_code_suggestions = get_settings().pr_code_suggestions.num_code_suggestions
self.ai_handler = ai_handler() self.ai_handler = ai_handler()
self.ai_handler.main_pr_language = self.main_language
self.patches_diff = None self.patches_diff = None
self.prediction = None self.prediction = None
self.cli_mode = cli_mode self.cli_mode = cli_mode
@ -56,7 +57,6 @@ class PRCodeSuggestions:
"language": self.main_language, "language": self.main_language,
"diff": "", # empty diff for initial calculation "diff": "", # empty diff for initial calculation
"num_code_suggestions": num_code_suggestions, "num_code_suggestions": num_code_suggestions,
"summarize_mode": get_settings().pr_code_suggestions.summarize,
"extra_instructions": get_settings().pr_code_suggestions.extra_instructions, "extra_instructions": get_settings().pr_code_suggestions.extra_instructions,
"commit_messages_str": self.git_provider.get_commit_messages(), "commit_messages_str": self.git_provider.get_commit_messages(),
} }
@ -75,21 +75,22 @@ class PRCodeSuggestions:
relevant_configs = {'pr_code_suggestions': dict(get_settings().pr_code_suggestions), relevant_configs = {'pr_code_suggestions': dict(get_settings().pr_code_suggestions),
'config': dict(get_settings().config)} 'config': dict(get_settings().config)}
get_logger().debug("Relevant configs", artifacts=relevant_configs) get_logger().debug("Relevant configs", artifacts=relevant_configs)
if get_settings().config.publish_output: if get_settings().config.publish_output and get_settings().config.publish_output_progress:
if self.git_provider.is_supported("gfm_markdown"): if self.git_provider.is_supported("gfm_markdown"):
self.progress_response = self.git_provider.publish_comment(self.progress) self.progress_response = self.git_provider.publish_comment(self.progress)
else: else:
self.git_provider.publish_comment("Preparing suggestions...", is_temporary=True) self.git_provider.publish_comment("Preparing suggestions...", is_temporary=True)
if not self.is_extended: if not self.is_extended:
await retry_with_fallback_models(self._prepare_prediction, ModelType.TURBO) data = await retry_with_fallback_models(self._prepare_prediction)
data = self._prepare_pr_code_suggestions()
else: else:
data = await retry_with_fallback_models(self._prepare_prediction_extended, ModelType.TURBO) data = await retry_with_fallback_models(self._prepare_prediction_extended)
if not data:
data = {"code_suggestions": []}
if (not data) or (not 'code_suggestions' in data) or (not data['code_suggestions']): if data is None or 'code_suggestions' not in data or not data['code_suggestions']:
get_logger().error('No code suggestions found for PR.') get_logger().error('No code suggestions found for PR.')
pr_body = "## PR Code Suggestions\n\nNo code suggestions found for PR." pr_body = "## PR Code Suggestions\n\nNo code suggestions found for PR."
get_logger().debug(f"PR output", artifact=pr_body) get_logger().debug(f"PR output", artifact=pr_body)
if self.progress_response: if self.progress_response:
self.git_provider.edit_comment(self.progress_response, body=pr_body) self.git_provider.edit_comment(self.progress_response, body=pr_body)
@ -104,7 +105,8 @@ class PRCodeSuggestions:
if get_settings().config.publish_output: if get_settings().config.publish_output:
self.git_provider.remove_initial_comment() self.git_provider.remove_initial_comment()
if get_settings().pr_code_suggestions.summarize and self.git_provider.is_supported("gfm_markdown"): if ((not get_settings().pr_code_suggestions.commitable_code_suggestions) and
self.git_provider.is_supported("gfm_markdown")):
# generate summarized suggestions # generate summarized suggestions
pr_body = self.generate_summarized_suggestions(data) pr_body = self.generate_summarized_suggestions(data)
@ -112,14 +114,29 @@ class PRCodeSuggestions:
# add usage guide # add usage guide
if get_settings().pr_code_suggestions.enable_help_text: if get_settings().pr_code_suggestions.enable_help_text:
pr_body += "<hr>\n\n<details> <summary><strong>✨ Improve tool usage guide:</strong></summary><hr> \n\n" pr_body += "<hr>\n\n<details> <summary><strong>💡 Tool usage guide:</strong></summary><hr> \n\n"
pr_body += HelpMessage.get_improve_usage_guide() pr_body += HelpMessage.get_improve_usage_guide()
pr_body += "\n</details>\n" pr_body += "\n</details>\n"
if self.progress_response: # Output the relevant configurations if enabled
self.git_provider.edit_comment(self.progress_response, body=pr_body) if get_settings().get('config', {}).get('output_relevant_configurations', False):
pr_body += show_relevant_configurations(relevant_section='pr_code_suggestions')
if get_settings().pr_code_suggestions.persistent_comment:
final_update_message = False
self.git_provider.publish_persistent_comment(pr_body,
initial_header="## PR Code Suggestions ✨",
update_header=True,
name="suggestions",
final_update_message=final_update_message, )
if self.progress_response:
self.progress_response.delete()
else: else:
self.git_provider.publish_comment(pr_body)
if self.progress_response:
self.git_provider.edit_comment(self.progress_response, body=pr_body)
else:
self.git_provider.publish_comment(pr_body)
else: else:
self.push_inline_code_suggestions(data) self.push_inline_code_suggestions(data)
@ -136,7 +153,7 @@ class PRCodeSuggestions:
except Exception as e: except Exception as e:
pass pass
async def _prepare_prediction(self, model: str): async def _prepare_prediction(self, model: str) -> dict:
self.patches_diff = get_pr_diff(self.git_provider, self.patches_diff = get_pr_diff(self.git_provider,
self.token_handler, self.token_handler,
model, model,
@ -150,7 +167,10 @@ class PRCodeSuggestions:
get_logger().error(f"Error getting PR diff") get_logger().error(f"Error getting PR diff")
self.prediction = None self.prediction = None
async def _get_prediction(self, model: str, patches_diff: str): data = self.prediction
return data
async def _get_prediction(self, model: str, patches_diff: str) -> dict:
variables = copy.deepcopy(self.vars) variables = copy.deepcopy(self.vars)
variables["diff"] = patches_diff # update diff variables["diff"] = patches_diff # update diff
environment = Environment(undefined=StrictUndefined) environment = Environment(undefined=StrictUndefined)
@ -159,7 +179,34 @@ class PRCodeSuggestions:
response, finish_reason = await self.ai_handler.chat_completion(model=model, temperature=0.2, response, finish_reason = await self.ai_handler.chat_completion(model=model, temperature=0.2,
system=system_prompt, user=user_prompt) system=system_prompt, user=user_prompt)
return response # load suggestions from the AI response
data = self._prepare_pr_code_suggestions(response)
# self-reflect on suggestions
if get_settings().pr_code_suggestions.self_reflect_on_suggestions:
model = get_settings().config.model_turbo # use turbo model for self-reflection, since it is an easier task
response_reflect = await self.self_reflect_on_suggestions(data["code_suggestions"], patches_diff, model=model)
if response_reflect:
response_reflect_yaml = load_yaml(response_reflect)
code_suggestions_feedback = response_reflect_yaml["code_suggestions"]
if len(code_suggestions_feedback) == len(data["code_suggestions"]):
for i, suggestion in enumerate(data["code_suggestions"]):
try:
suggestion["score"] = code_suggestions_feedback[i]["suggestion_score"]
suggestion["score_why"] = code_suggestions_feedback[i]["why"]
except Exception as e: #
get_logger().error(f"Error processing suggestion score {i}",
artifact={"suggestion": suggestion,
"code_suggestions_feedback": code_suggestions_feedback[i]})
suggestion["score"] = 7
suggestion["score_why"] = ""
else:
# get_logger().error(f"Could not self-reflect on suggestions. using default score 7")
for i, suggestion in enumerate(data["code_suggestions"]):
suggestion["score"] = 7
suggestion["score_why"] = ""
return data
@staticmethod @staticmethod
def _truncate_if_needed(suggestion): def _truncate_if_needed(suggestion):
@ -173,19 +220,19 @@ class PRCodeSuggestions:
f"characters to {max_code_suggestion_length} characters") f"characters to {max_code_suggestion_length} characters")
return suggestion return suggestion
def _prepare_pr_code_suggestions(self) -> Dict: def _prepare_pr_code_suggestions(self, predictions: str) -> Dict:
review = self.prediction.strip() data = load_yaml(predictions.strip(),
data = load_yaml(review,
keys_fix_yaml=["relevant_file", "suggestion_content", "existing_code", "improved_code"]) keys_fix_yaml=["relevant_file", "suggestion_content", "existing_code", "improved_code"])
if isinstance(data, list): if isinstance(data, list):
data = {'code_suggestions': data} data = {'code_suggestions': data}
# remove invalid suggestions # remove or edit invalid suggestions
suggestion_list = [] suggestion_list = []
one_sentence_summary_list = [] one_sentence_summary_list = []
for i, suggestion in enumerate(data['code_suggestions']): for i, suggestion in enumerate(data['code_suggestions']):
if get_settings().pr_code_suggestions.summarize: try:
if not suggestion or 'one_sentence_summary' not in suggestion or 'label' not in suggestion or 'relevant_file' not in suggestion: if (not suggestion or 'one_sentence_summary' not in suggestion or
'label' not in suggestion or 'relevant_file' not in suggestion):
get_logger().debug(f"Skipping suggestion {i + 1}, because it is invalid: {suggestion}") get_logger().debug(f"Skipping suggestion {i + 1}, because it is invalid: {suggestion}")
continue continue
@ -193,15 +240,26 @@ class PRCodeSuggestions:
get_logger().debug(f"Skipping suggestion {i + 1}, because it is a duplicate: {suggestion}") get_logger().debug(f"Skipping suggestion {i + 1}, because it is a duplicate: {suggestion}")
continue continue
if ('existing_code' in suggestion) and ('improved_code' in suggestion) and ( if 'const' in suggestion['suggestion_content'] and 'instead' in suggestion['suggestion_content'] and 'let' in suggestion['suggestion_content']:
suggestion['existing_code'] != suggestion['improved_code']): get_logger().debug(f"Skipping suggestion {i + 1}, because it uses 'const instead let': {suggestion}")
suggestion = self._truncate_if_needed(suggestion) continue
if get_settings().pr_code_suggestions.summarize:
if ('existing_code' in suggestion) and ('improved_code' in suggestion):
if suggestion['existing_code'] == suggestion['improved_code']:
get_logger().debug(
f"edited improved suggestion {i + 1}, because equal to existing code: {suggestion['existing_code']}")
if get_settings().pr_code_suggestions.commitable_code_suggestions:
suggestion['improved_code'] = "" # we need 'existing_code' to locate the code in the PR
else:
suggestion['existing_code'] = ""
suggestion = self._truncate_if_needed(suggestion)
one_sentence_summary_list.append(suggestion['one_sentence_summary']) one_sentence_summary_list.append(suggestion['one_sentence_summary'])
suggestion_list.append(suggestion) suggestion_list.append(suggestion)
else: else:
get_logger().debug( get_logger().info(
f"Skipping suggestion {i + 1}, because existing code is equal to improved code {suggestion['existing_code']}") f"Skipping suggestion {i + 1}, because it does not contain 'existing_code' or 'improved_code': {suggestion}")
except Exception as e:
get_logger().error(f"Error processing suggestion {i + 1}: {suggestion}, error: {e}")
data['code_suggestions'] = suggestion_list data['code_suggestions'] = suggestion_list
return data return data
@ -228,7 +286,10 @@ class PRCodeSuggestions:
if new_code_snippet: if new_code_snippet:
new_code_snippet = self.dedent_code(relevant_file, relevant_lines_start, new_code_snippet) new_code_snippet = self.dedent_code(relevant_file, relevant_lines_start, new_code_snippet)
body = f"**Suggestion:** {content} [{label}]\n```suggestion\n" + new_code_snippet + "\n```" if d.get('score'):
body = f"**Suggestion:** {content} [{label}, importance: {d.get('score')}]\n```suggestion\n" + new_code_snippet + "\n```"
else:
body = f"**Suggestion:** {content} [{label}]\n```suggestion\n" + new_code_snippet + "\n```"
code_suggestions.append({'body': body, 'relevant_file': relevant_file, code_suggestions.append({'body': body, 'relevant_file': relevant_file,
'relevant_lines_start': relevant_lines_start, 'relevant_lines_start': relevant_lines_start,
'relevant_lines_end': relevant_lines_end}) 'relevant_lines_end': relevant_lines_end})
@ -277,7 +338,8 @@ class PRCodeSuggestions:
self.patches_diff_list = get_pr_multi_diffs(self.git_provider, self.token_handler, model, self.patches_diff_list = get_pr_multi_diffs(self.git_provider, self.token_handler, model,
max_calls=get_settings().pr_code_suggestions.max_number_of_calls) max_calls=get_settings().pr_code_suggestions.max_number_of_calls)
if self.patches_diff_list: if self.patches_diff_list:
get_logger().debug(f"PR diff", artifact=self.patches_diff_list) get_logger().info(f"Number of PR chunk calls: {len(self.patches_diff_list)}")
get_logger().debug(f"PR diff:", artifact=self.patches_diff_list)
# parallelize calls to AI: # parallelize calls to AI:
if get_settings().pr_code_suggestions.parallel_calls: if get_settings().pr_code_suggestions.parallel_calls:
@ -290,14 +352,24 @@ class PRCodeSuggestions:
prediction = await self._get_prediction(model, patches_diff) prediction = await self._get_prediction(model, patches_diff)
prediction_list.append(prediction) prediction_list.append(prediction)
data = {} data = {"code_suggestions": []}
for prediction in prediction_list: for j, predictions in enumerate(prediction_list): # each call adds an element to the list
self.prediction = prediction if "code_suggestions" in predictions:
data_per_chunk = self._prepare_pr_code_suggestions() score_threshold = max(1, get_settings().pr_code_suggestions.suggestions_score_threshold)
if "code_suggestions" in data: for i, prediction in enumerate(predictions["code_suggestions"]):
data["code_suggestions"].extend(data_per_chunk["code_suggestions"]) try:
else: if get_settings().pr_code_suggestions.self_reflect_on_suggestions:
data.update(data_per_chunk) score = int(prediction["score"])
if score >= score_threshold:
data["code_suggestions"].append(prediction)
else:
get_logger().info(
f"Removing suggestions {i} from call {j}, because score is {score}, and score_threshold is {score_threshold}",
artifact=prediction)
else:
data["code_suggestions"].append(prediction)
except Exception as e:
get_logger().error(f"Error getting PR diff for suggestion {i} in call {j}, error: {e}")
self.data = data self.data = data
else: else:
get_logger().error(f"Error getting PR diff") get_logger().error(f"Error getting PR diff")
@ -363,7 +435,7 @@ class PRCodeSuggestions:
def generate_summarized_suggestions(self, data: Dict) -> str: def generate_summarized_suggestions(self, data: Dict) -> str:
try: try:
pr_body = "## PR Code Suggestions\n\n" pr_body = "## PR Code Suggestions\n\n"
if len(data.get('code_suggestions', [])) == 0: if len(data.get('code_suggestions', [])) == 0:
pr_body += "No suggestions found to improve this PR." pr_body += "No suggestions found to improve this PR."
@ -375,13 +447,16 @@ class PRCodeSuggestions:
for ext in extensions: for ext in extensions:
extension_to_language[ext] = language extension_to_language[ext] = language
pr_body = "## PR Code Suggestions\n\n" pr_body = "## PR Code Suggestions\n\n"
pr_body += "<table>" pr_body += "<table>"
header = f"Suggestions" header = f"Suggestion"
delta = 76 delta = 66
header += "&nbsp; " * delta header += "&nbsp; " * delta
pr_body += f"""<thead><tr><td>Category</td><td align=left>{header}</td></tr></thead>""" if get_settings().pr_code_suggestions.self_reflect_on_suggestions:
pr_body += f"""<thead><tr><td>Category</td><td align=left>{header}</td><td align=center>Score</td></tr>"""
else:
pr_body += f"""<thead><tr><td>Category</td><td align=left>{header}</td></tr>"""
pr_body += """<tbody>""" pr_body += """<tbody>"""
suggestions_labels = dict() suggestions_labels = dict()
# add all suggestions related to each label # add all suggestions related to each label
@ -391,13 +466,17 @@ class PRCodeSuggestions:
suggestions_labels[label] = [] suggestions_labels[label] = []
suggestions_labels[label].append(suggestion) suggestions_labels[label].append(suggestion)
# sort suggestions_labels by the suggestion with the highest score
if get_settings().pr_code_suggestions.self_reflect_on_suggestions:
suggestions_labels = dict(sorted(suggestions_labels.items(), key=lambda x: max([s['score'] for s in x[1]]), reverse=True))
# sort the suggestions inside each label group by score
for label, suggestions in suggestions_labels.items():
suggestions_labels[label] = sorted(suggestions, key=lambda x: x['score'], reverse=True)
for label, suggestions in suggestions_labels.items(): for label, suggestions in suggestions_labels.items():
num_suggestions=len(suggestions) num_suggestions=len(suggestions)
# pr_body += f"""<tr><td><strong>{label}</strong></td>"""
pr_body += f"""<tr><td rowspan={num_suggestions}><strong>{label.capitalize()}</strong></td>\n""" pr_body += f"""<tr><td rowspan={num_suggestions}><strong>{label.capitalize()}</strong></td>\n"""
# pr_body += f"""<td>"""
# pr_body += f"""<details><summary>{len(suggestions)} suggestions</summary>"""
# pr_body += f"""<table>"""
for i, suggestion in enumerate(suggestions): for i, suggestion in enumerate(suggestions):
relevant_file = suggestion['relevant_file'].strip() relevant_file = suggestion['relevant_file'].strip()
@ -408,8 +487,12 @@ class PRCodeSuggestions:
range_str = f"[{relevant_lines_start}]" range_str = f"[{relevant_lines_start}]"
else: else:
range_str = f"[{relevant_lines_start}-{relevant_lines_end}]" range_str = f"[{relevant_lines_start}-{relevant_lines_end}]"
code_snippet_link = self.git_provider.get_line_link(relevant_file, relevant_lines_start,
relevant_lines_end) try:
code_snippet_link = self.git_provider.get_line_link(relevant_file, relevant_lines_start,
relevant_lines_end)
except:
code_snippet_link = ""
# add html table for each suggestion # add html table for each suggestion
suggestion_content = suggestion['suggestion_content'].rstrip().rstrip() suggestion_content = suggestion['suggestion_content'].rstrip().rstrip()
@ -430,12 +513,11 @@ class PRCodeSuggestions:
pr_body += f"""<td>\n\n""" pr_body += f"""<td>\n\n"""
else: else:
pr_body += f"""<tr><td>\n\n""" pr_body += f"""<tr><td>\n\n"""
suggestion_summary = suggestion['one_sentence_summary'].strip() suggestion_summary = suggestion['one_sentence_summary'].strip().rstrip('.')
if '`' in suggestion_summary: if '`' in suggestion_summary:
suggestion_summary = replace_code_tags(suggestion_summary) suggestion_summary = replace_code_tags(suggestion_summary)
# suggestion_summary = suggestion_summary + max((77-len(suggestion_summary)), 0)*"&nbsp;"
pr_body += f"""\n\n<details><summary>{suggestion_summary}</summary>\n\n___\n\n"""
pr_body += f"""\n\n<details><summary>{suggestion_summary}</summary>\n\n___\n\n"""
pr_body += f""" pr_body += f"""
**{suggestion_content}** **{suggestion_content}**
@ -443,14 +525,50 @@ class PRCodeSuggestions:
{example_code} {example_code}
""" """
if get_settings().pr_code_suggestions.self_reflect_on_suggestions:
pr_body +=f"\n\n<details><summary><b>Suggestion importance[1-10]: {suggestion['score']}</b></summary>\n\n"
pr_body += f"Why: {suggestion['score_why']}\n\n"
pr_body += f"</details>"
pr_body += f"</details>" pr_body += f"</details>"
# # add another column for 'score'
if get_settings().pr_code_suggestions.self_reflect_on_suggestions:
pr_body += f"</td><td align=center>{suggestion['score']}\n\n"
pr_body += f"</td></tr>" pr_body += f"</td></tr>"
# pr_body += "</details>" # pr_body += "</details>"
pr_body += """</td></tr>""" # pr_body += """</td></tr>"""
pr_body += """</tr></tbody></table>""" pr_body += """</tr></tbody></table>"""
return pr_body return pr_body
except Exception as e: except Exception as e:
get_logger().info(f"Failed to publish summarized code suggestions, error: {e}") get_logger().info(f"Failed to publish summarized code suggestions, error: {e}")
return "" return ""
async def self_reflect_on_suggestions(self, suggestion_list: List, patches_diff: str, model: str) -> str:
if not suggestion_list:
return ""
try:
suggestion_str = ""
for i, suggestion in enumerate(suggestion_list):
suggestion_str += f"suggestion {i + 1}: " + str(suggestion) + '\n\n'
variables = {'suggestion_list': suggestion_list,
'suggestion_str': suggestion_str,
"diff": patches_diff,
'num_code_suggestions': len(suggestion_list)}
environment = Environment(undefined=StrictUndefined)
system_prompt_reflect = environment.from_string(get_settings().pr_code_suggestions_reflect_prompt.system).render(
variables)
user_prompt_reflect = environment.from_string(get_settings().pr_code_suggestions_reflect_prompt.user).render(variables)
with get_logger().contextualize(command="self_reflect_on_suggestions"):
response_reflect, finish_reason_reflect = await self.ai_handler.chat_completion(model=model,
system=system_prompt_reflect,
user=user_prompt_reflect)
except Exception as e:
get_logger().info(f"Could not reflect on suggestions, error: {e}")
return ""
return response_reflect

View File

@ -9,7 +9,7 @@ from pr_agent.algo.ai_handlers.base_ai_handler import BaseAiHandler
from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
from pr_agent.algo.token_handler import TokenHandler from pr_agent.algo.token_handler import TokenHandler
from pr_agent.algo.utils import load_yaml, set_custom_labels, get_user_labels, ModelType from pr_agent.algo.utils import load_yaml, set_custom_labels, get_user_labels, ModelType, show_relevant_configurations
from pr_agent.config_loader import get_settings from pr_agent.config_loader import get_settings
from pr_agent.git_providers import get_git_provider from pr_agent.git_providers import get_git_provider
from pr_agent.git_providers.git_provider import get_main_pr_language from pr_agent.git_providers.git_provider import get_main_pr_language
@ -41,6 +41,7 @@ class PRDescription:
# Initialize the AI handler # Initialize the AI handler
self.ai_handler = ai_handler() self.ai_handler = ai_handler()
self.ai_handler.main_pr_language = self.main_pr_language
# Initialize the variables dictionary # Initialize the variables dictionary
@ -81,7 +82,7 @@ class PRDescription:
if get_settings().config.publish_output: if get_settings().config.publish_output:
self.git_provider.publish_comment("Preparing PR description...", is_temporary=True) self.git_provider.publish_comment("Preparing PR description...", is_temporary=True)
await retry_with_fallback_models(self._prepare_prediction, ModelType.TURBO) # turbo model because larger context await retry_with_fallback_models(self._prepare_prediction, ModelType.TURBO)
if self.prediction: if self.prediction:
self._prepare_data() self._prepare_data()
@ -112,22 +113,37 @@ class PRDescription:
pr_body += HelpMessage.get_describe_usage_guide() pr_body += HelpMessage.get_describe_usage_guide()
pr_body += "\n</details>\n" pr_body += "\n</details>\n"
elif get_settings().pr_description.enable_help_comment: elif get_settings().pr_description.enable_help_comment:
pr_body += "\n\n___\n\n> **PR-Agent usage**:" pr_body += "\n\n___\n\n> 💡 **PR-Agent usage**:"
pr_body += "\n>Comment `/help` on the PR to get a list of all available PR-Agent tools and their descriptions\n\n" pr_body += "\n>Comment `/help` on the PR to get a list of all available PR-Agent tools and their descriptions\n\n"
# Output the relevant configurations if enabled
if get_settings().get('config', {}).get('output_relevant_configurations', False):
pr_body += show_relevant_configurations(relevant_section='pr_description')
if get_settings().config.publish_output: if get_settings().config.publish_output:
# publish labels # publish labels
if get_settings().pr_description.publish_labels and self.git_provider.is_supported("get_labels"): if get_settings().pr_description.publish_labels and self.git_provider.is_supported("get_labels"):
original_labels = self.git_provider.get_pr_labels() original_labels = self.git_provider.get_pr_labels(update=True)
get_logger().debug(f"original labels", artifact=original_labels) get_logger().debug(f"original labels", artifact=original_labels)
user_labels = get_user_labels(original_labels) user_labels = get_user_labels(original_labels)
get_logger().debug(f"published labels:\n{pr_labels + user_labels}") new_labels = pr_labels + user_labels
self.git_provider.publish_labels(pr_labels + user_labels) get_logger().debug(f"published labels", artifact=new_labels)
if sorted(new_labels) != sorted(original_labels):
self.git_provider.publish_labels(new_labels)
else:
get_logger().debug(f"Labels are the same, not updating")
# publish description # publish description
if get_settings().pr_description.publish_description_as_comment: if get_settings().pr_description.publish_description_as_comment:
full_markdown_description = f"## Title\n\n{pr_title}\n\n___\n{pr_body}" full_markdown_description = f"## Title\n\n{pr_title}\n\n___\n{pr_body}"
self.git_provider.publish_comment(full_markdown_description) if get_settings().pr_description.publish_description_as_comment_persistent:
self.git_provider.publish_persistent_comment(full_markdown_description,
initial_header="## Title",
update_header=True,
name="describe",
final_update_message=False, )
else:
self.git_provider.publish_comment(full_markdown_description)
else: else:
self.git_provider.publish_description(pr_title, pr_body) self.git_provider.publish_description(pr_title, pr_body)
@ -289,7 +305,7 @@ class PRDescription:
# Remove the 'PR Title' key from the dictionary # Remove the 'PR Title' key from the dictionary
ai_title = self.data.pop('title', self.vars["title"]) ai_title = self.data.pop('title', self.vars["title"])
if get_settings().pr_description.keep_original_user_title: if (not get_settings().pr_description.generate_ai_title):
# Assign the original PR title to the 'title' variable # Assign the original PR title to the 'title' variable
title = self.vars["title"] title = self.vars["title"]
else: else:
@ -305,7 +321,11 @@ class PRDescription:
value = self.file_label_dict value = self.file_label_dict
else: else:
key_publish = key.rstrip(':').replace("_", " ").capitalize() key_publish = key.rstrip(':').replace("_", " ").capitalize()
pr_body += f"## **{key_publish}**\n" if key_publish== "Type":
key_publish = "PR Type"
# elif key_publish == "Description":
# key_publish = "PR Description"
pr_body += f"### **{key_publish}**\n"
if 'walkthrough' in key.lower(): if 'walkthrough' in key.lower():
if self.git_provider.is_supported("gfm_markdown"): if self.git_provider.is_supported("gfm_markdown"):
pr_body += "<details> <summary>files:</summary>\n\n" pr_body += "<details> <summary>files:</summary>\n\n"
@ -317,7 +337,7 @@ class PRDescription:
pr_body += "</details>\n" pr_body += "</details>\n"
elif 'pr_files' in key.lower(): elif 'pr_files' in key.lower():
changes_walkthrough, pr_file_changes = self.process_pr_files_prediction(changes_walkthrough, value) changes_walkthrough, pr_file_changes = self.process_pr_files_prediction(changes_walkthrough, value)
changes_walkthrough = f"## **Changes walkthrough**\n{changes_walkthrough}" changes_walkthrough = f"### **Changes walkthrough** 📝\n{changes_walkthrough}"
else: else:
# if the value is a list, join its items by comma # if the value is a list, join its items by comma
if isinstance(value, list): if isinstance(value, list):

View File

@ -35,7 +35,8 @@ class PRGenerateLabels:
# Initialize the AI handler # Initialize the AI handler
self.ai_handler = ai_handler() self.ai_handler = ai_handler()
self.ai_handler.main_pr_language = self.main_pr_language
# Initialize the variables dictionary # Initialize the variables dictionary
self.vars = { self.vars = {
"title": self.git_provider.pr.title, "title": self.git_provider.pr.title,

View File

@ -18,60 +18,67 @@ class PRHelpMessage:
relevant_configs = {'pr_help': dict(get_settings().pr_help), relevant_configs = {'pr_help': dict(get_settings().pr_help),
'config': dict(get_settings().config)} 'config': dict(get_settings().config)}
get_logger().debug("Relevant configs", artifacts=relevant_configs) get_logger().debug("Relevant configs", artifacts=relevant_configs)
pr_comment = "## PR Agent Walkthrough\n\n" pr_comment = "## PR Agent Walkthrough 🤖\n\n"
pr_comment += "🤖 Welcome to the PR Agent, an AI-powered tool for automated pull request analysis, feedback, suggestions and more.""" pr_comment += "Welcome to the PR Agent, an AI-powered tool for automated pull request analysis, feedback, suggestions and more."""
pr_comment += "\n\nHere is a list of tools you can use to interact with the PR Agent:\n" pr_comment += "\n\nHere is a list of tools you can use to interact with the PR Agent:\n"
base_path = "https://github.com/Codium-ai/pr-agent/tree/main/docs" base_path = "https://pr-agent-docs.codium.ai/tools"
tool_names = [] tool_names = []
tool_names.append(f"[DESCRIBE]({base_path}/DESCRIBE.md)") tool_names.append(f"[DESCRIBE]({base_path}/describe/)")
tool_names.append(f"[REVIEW]({base_path}/REVIEW.md)") tool_names.append(f"[REVIEW]({base_path}/review/)")
tool_names.append(f"[IMPROVE]({base_path}/IMPROVE.md)") tool_names.append(f"[IMPROVE]({base_path}/improve/)")
tool_names.append(f"[ANALYZE]({base_path}/Analyze.md) 💎") tool_names.append(f"[UPDATE CHANGELOG]({base_path}/update_changelog/)")
tool_names.append(f"[UPDATE CHANGELOG]({base_path}/UPDATE_CHANGELOG.md)") tool_names.append(f"[ADD DOCS]({base_path}/documentation/) 💎")
tool_names.append(f"[ADD DOCUMENTATION]({base_path}/ADD_DOCUMENTATION.md) 💎") tool_names.append(f"[TEST]({base_path}/test/) 💎")
tool_names.append(f"[ASK]({base_path}/ASK.md)") tool_names.append(f"[IMPROVE COMPONENT]({base_path}/improve_component/) 💎")
tool_names.append(f"[GENERATE CUSTOM LABELS]({base_path}/GENERATE_CUSTOM_LABELS.md)") tool_names.append(f"[ANALYZE]({base_path}/analyze/) 💎")
tool_names.append(f"[TEST]({base_path}/TEST.md) 💎") tool_names.append(f"[ASK]({base_path}/ask/)")
tool_names.append(f"[CI FEEDBACK]({base_path}/CI_FEEDBACK.md) 💎") tool_names.append(f"[GENERATE CUSTOM LABELS]({base_path}/custom_labels/) 💎")
tool_names.append(f"[CUSTOM SUGGESTIONS]({base_path}/CUSTOM_SUGGESTIONS.md) 💎") tool_names.append(f"[CI FEEDBACK]({base_path}/ci_feedback/) 💎")
tool_names.append(f"[SIMILAR ISSUE]({base_path}/SIMILAR_ISSUE.md)") tool_names.append(f"[CUSTOM PROMPT]({base_path}/custom_prompt/) 💎")
tool_names.append(f"[SIMILAR ISSUE]({base_path}/similar_issues/)")
descriptions = [] descriptions = []
descriptions.append("Generates PR description - title, type, summary, code walkthrough and labels") descriptions.append("Generates PR description - title, type, summary, code walkthrough and labels")
descriptions.append("Adjustable feedback about the PR, possible issues, security concerns, review effort and more") descriptions.append("Adjustable feedback about the PR, possible issues, security concerns, review effort and more")
descriptions.append("Code suggestions for improving the PR.") descriptions.append("Code suggestions for improving the PR")
descriptions.append("Identifies code components that changed in the PR, and enables to interactively generate tests, docs, and code suggestions for each component.") descriptions.append("Automatically updates the changelog")
descriptions.append("Automatically updates the changelog.") descriptions.append("Generates documentation to methods/functions/classes that changed in the PR")
descriptions.append("Generates documentation to methods/functions/classes that changed in the PR.") descriptions.append("Generates unit tests for a specific component, based on the PR code change")
descriptions.append("Answering free-text questions about the PR.") descriptions.append("Code suggestions for a specific component that changed in the PR")
descriptions.append("Identifies code components that changed in the PR, and enables to interactively generate tests, docs, and code suggestions for each component")
descriptions.append("Answering free-text questions about the PR")
descriptions.append("Generates custom labels for the PR, based on specific guidelines defined by the user") descriptions.append("Generates custom labels for the PR, based on specific guidelines defined by the user")
descriptions.append("Generates unit tests for a specific component, based on the PR code change.") descriptions.append("Generates feedback and analysis for a failed CI job")
descriptions.append("Generates feedback and analysis for a failed CI job.") descriptions.append("Generates custom suggestions for improving the PR code, derived only from a specific guidelines prompt defined by the user")
descriptions.append("Generates custom suggestions for improving the PR code, based on specific guidelines defined by the user.") descriptions.append("Automatically retrieves and presents similar issues")
descriptions.append("Automatically retrieves and presents similar issues.")
commands =[] commands =[]
commands.append("`/describe`") commands.append("`/describe`")
commands.append("`/review`") commands.append("`/review`")
commands.append("`/improve`") commands.append("`/improve`")
commands.append("`/analyze`")
commands.append("`/update_changelog`") commands.append("`/update_changelog`")
commands.append("`/add_docs`") commands.append("`/add_docs`")
commands.append("`/test`")
commands.append("`/improve_component`")
commands.append("`/analyze`")
commands.append("`/ask`") commands.append("`/ask`")
commands.append("`/generate_labels`") commands.append("`/generate_labels`")
commands.append("`/test`")
commands.append("`/checks`") commands.append("`/checks`")
commands.append("`/custom_suggestions`") commands.append("`/custom_prompt`")
commands.append("`/similar_issue`") commands.append("`/similar_issue`")
checkbox_list = [] checkbox_list = []
checkbox_list.append(" - [ ] Run <!-- /describe -->") checkbox_list.append(" - [ ] Run <!-- /describe -->")
checkbox_list.append(" - [ ] Run <!-- /review -->") checkbox_list.append(" - [ ] Run <!-- /review -->")
checkbox_list.append(" - [ ] Run <!-- /improve -->") checkbox_list.append(" - [ ] Run <!-- /improve -->")
checkbox_list.append(" - [ ] Run <!-- /analyze -->")
checkbox_list.append(" - [ ] Run <!-- /update_changelog -->") checkbox_list.append(" - [ ] Run <!-- /update_changelog -->")
checkbox_list.append(" - [ ] Run <!-- /add_docs -->") checkbox_list.append(" - [ ] Run <!-- /add_docs -->")
checkbox_list.append(" - [ ] Run <!-- /test -->")
checkbox_list.append(" - [ ] Run <!-- /improve_component -->")
checkbox_list.append(" - [ ] Run <!-- /analyze -->")
checkbox_list.append("[*]")
checkbox_list.append("[*]")
checkbox_list.append("[*]") checkbox_list.append("[*]")
checkbox_list.append("[*]") checkbox_list.append("[*]")
checkbox_list.append("[*]") checkbox_list.append("[*]")
@ -79,19 +86,19 @@ class PRHelpMessage:
checkbox_list.append("[*]") checkbox_list.append("[*]")
checkbox_list.append("[*]") checkbox_list.append("[*]")
if isinstance(self.git_provider, GithubProvider): if isinstance(self.git_provider, GithubProvider) and not get_settings().config.get('disable_checkboxes', False):
pr_comment += f"<table><tr align='center'><th align='center'>Tool</th><th align='center'>Description</th><th align='center'>Invoke Interactively :gem:</th></tr>" pr_comment += f"<table><tr align='left'><th align='left'>Tool</th><th align='left'>Description</th><th align='left'>Trigger Interactively :gem:</th></tr>"
for i in range(len(tool_names)): for i in range(len(tool_names)):
pr_comment += f"\n<tr><td align='center'>\n\n<strong>{tool_names[i]}</strong></td>\n<td>{descriptions[i]}</td>\n<td>\n\n{checkbox_list[i]}\n</td></tr>" pr_comment += f"\n<tr><td align='left'>\n\n<strong>{tool_names[i]}</strong></td>\n<td>{descriptions[i]}</td>\n<td>\n\n{checkbox_list[i]}\n</td></tr>"
pr_comment += "</table>\n\n" pr_comment += "</table>\n\n"
pr_comment += f"""\n\n(1) Note that each tool be [triggered automatically](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#github-app-automatic-tools-for-pr-actions) when a new PR is opened, or called manually by [commenting on a PR](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#online-usage).""" pr_comment += f"""\n\n(1) Note that each tool be [triggered automatically](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#github-app-automatic-tools-for-pr-actions) when a new PR is opened, or called manually by [commenting on a PR](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#online-usage)."""
pr_comment += f"""\n\n(2) Tools marked with [*] require additional parameters to be passed. For example, to invoke the `/ask` tool, you need to comment on a PR: `/ask "<question content>"`. See the relevant documentation for each tool for more details.""" pr_comment += f"""\n\n(2) Tools marked with [*] require additional parameters to be passed. For example, to invoke the `/ask` tool, you need to comment on a PR: `/ask "<question content>"`. See the relevant documentation for each tool for more details."""
else: else:
pr_comment += f"<table><tr align='center'><th align='center'>Tool</th><th align='left'>Command</th><th align='left'>Description</th></tr>" pr_comment += f"<table><tr align='left'><th align='left'>Tool</th><th align='left'>Command</th><th align='left'>Description</th></tr>"
for i in range(len(tool_names)): for i in range(len(tool_names)):
pr_comment += f"\n<tr><td align='center'>\n\n<strong>{tool_names[i]}</strong></td><td>{commands[i]}</td><td>{descriptions[i]}</td></tr>" pr_comment += f"\n<tr><td align='left'>\n\n<strong>{tool_names[i]}</strong></td><td>{commands[i]}</td><td>{descriptions[i]}</td></tr>"
pr_comment += "</table>\n\n" pr_comment += "</table>\n\n"
pr_comment += f"""\n\nNote that each tool be [invoked automatically](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#github-app-automatic-tools-for-pr-actions) when a new PR is opened, or called manually by [commenting on a PR](https://github.com/Codium-ai/pr-agent/blob/main/Usage.md#online-usage).""" pr_comment += f"""\n\nNote that each tool be [invoked automatically](https://pr-agent-docs.codium.ai/usage-guide/automations_and_usage/) when a new PR is opened, or called manually by [commenting on a PR](https://pr-agent-docs.codium.ai/usage-guide/automations_and_usage/#online-usage)."""
if get_settings().config.publish_output: if get_settings().config.publish_output:
self.git_provider.publish_comment(pr_comment) self.git_provider.publish_comment(pr_comment)
except Exception as e: except Exception as e:

View File

@ -21,6 +21,8 @@ class PRInformationFromUser:
self.git_provider.get_languages(), self.git_provider.get_files() self.git_provider.get_languages(), self.git_provider.get_files()
) )
self.ai_handler = ai_handler() self.ai_handler = ai_handler()
self.ai_handler.main_pr_language = self.main_pr_language
self.vars = { self.vars = {
"title": self.git_provider.pr.title, "title": self.git_provider.pr.title,
"branch": self.git_provider.get_pr_branch(), "branch": self.git_provider.get_pr_branch(),

View File

@ -22,8 +22,11 @@ class PR_LineQuestions:
def __init__(self, pr_url: str, args=None, ai_handler: partial[BaseAiHandler,] = LiteLLMAIHandler): def __init__(self, pr_url: str, args=None, ai_handler: partial[BaseAiHandler,] = LiteLLMAIHandler):
self.question_str = self.parse_args(args) self.question_str = self.parse_args(args)
self.git_provider = get_git_provider()(pr_url) self.git_provider = get_git_provider()(pr_url)
self.main_pr_language = get_main_pr_language(
self.git_provider.get_languages(), self.git_provider.get_files()
)
self.ai_handler = ai_handler() self.ai_handler = ai_handler()
self.ai_handler.main_pr_language = self.main_pr_language
self.vars = { self.vars = {
"title": self.git_provider.pr.title, "title": self.git_provider.pr.title,

View File

@ -7,6 +7,7 @@ from pr_agent.algo.ai_handlers.base_ai_handler import BaseAiHandler
from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
from pr_agent.algo.token_handler import TokenHandler from pr_agent.algo.token_handler import TokenHandler
from pr_agent.algo.utils import ModelType
from pr_agent.config_loader import get_settings from pr_agent.config_loader import get_settings
from pr_agent.git_providers import get_git_provider from pr_agent.git_providers import get_git_provider
from pr_agent.git_providers.git_provider import get_main_pr_language from pr_agent.git_providers.git_provider import get_main_pr_language
@ -17,11 +18,14 @@ from pr_agent.servers.help import HelpMessage
class PRQuestions: class PRQuestions:
def __init__(self, pr_url: str, args=None, ai_handler: partial[BaseAiHandler,] = LiteLLMAIHandler): def __init__(self, pr_url: str, args=None, ai_handler: partial[BaseAiHandler,] = LiteLLMAIHandler):
question_str = self.parse_args(args) question_str = self.parse_args(args)
self.pr_url = pr_url
self.git_provider = get_git_provider()(pr_url) self.git_provider = get_git_provider()(pr_url)
self.main_pr_language = get_main_pr_language( self.main_pr_language = get_main_pr_language(
self.git_provider.get_languages(), self.git_provider.get_files() self.git_provider.get_languages(), self.git_provider.get_files()
) )
self.ai_handler = ai_handler() self.ai_handler = ai_handler()
self.ai_handler.main_pr_language = self.main_pr_language
self.question_str = question_str self.question_str = question_str
self.vars = { self.vars = {
"title": self.git_provider.pr.title, "title": self.git_provider.pr.title,
@ -47,19 +51,25 @@ class PRQuestions:
return question_str return question_str
async def run(self): async def run(self):
get_logger().info('Answering a PR question...') get_logger().info(f'Answering a PR question about the PR {self.pr_url} ')
relevant_configs = {'pr_questions': dict(get_settings().pr_questions), relevant_configs = {'pr_questions': dict(get_settings().pr_questions),
'config': dict(get_settings().config)} 'config': dict(get_settings().config)}
get_logger().debug("Relevant configs", artifacts=relevant_configs) get_logger().debug("Relevant configs", artifacts=relevant_configs)
if get_settings().config.publish_output: if get_settings().config.publish_output:
self.git_provider.publish_comment("Preparing answer...", is_temporary=True) self.git_provider.publish_comment("Preparing answer...", is_temporary=True)
await retry_with_fallback_models(self._prepare_prediction)
# identify image
img_path = self.idenfity_image_in_comment()
if img_path:
get_logger().debug(f"Image path identified", artifact=img_path)
await retry_with_fallback_models(self._prepare_prediction, model_type=ModelType.TURBO)
pr_comment = self._prepare_pr_answer() pr_comment = self._prepare_pr_answer()
get_logger().debug(f"PR output", artifact=pr_comment) get_logger().debug(f"PR output", artifact=pr_comment)
if self.git_provider.is_supported("gfm_markdown") and get_settings().pr_questions.enable_help_text: if self.git_provider.is_supported("gfm_markdown") and get_settings().pr_questions.enable_help_text:
pr_comment += "<hr>\n\n<details> <summary><strong>✨ Ask tool usage guide:</strong></summary><hr> \n\n" pr_comment += "<hr>\n\n<details> <summary><strong>💡 Tool usage guide:</strong></summary><hr> \n\n"
pr_comment += HelpMessage.get_ask_usage_guide() pr_comment += HelpMessage.get_ask_usage_guide()
pr_comment += "\n</details>\n" pr_comment += "\n</details>\n"
@ -68,6 +78,19 @@ class PRQuestions:
self.git_provider.remove_initial_comment() self.git_provider.remove_initial_comment()
return "" return ""
def idenfity_image_in_comment(self):
img_path = ''
if '![image]' in self.question_str:
# assuming structure:
# /ask question ... > ![image](img_path)
img_path = self.question_str.split('![image]')[1].strip().strip('()')
self.vars['img_path'] = img_path
elif 'https://' in self.question_str and ('.png' in self.question_str or 'jpg' in self.question_str): # direct image link
# include https:// in the image path
img_path = 'https://' + self.question_str.split('https://')[1]
self.vars['img_path'] = img_path
return img_path
async def _prepare_prediction(self, model: str): async def _prepare_prediction(self, model: str):
self.patches_diff = get_pr_diff(self.git_provider, self.token_handler, model) self.patches_diff = get_pr_diff(self.git_provider, self.token_handler, model)
if self.patches_diff: if self.patches_diff:
@ -83,11 +106,17 @@ class PRQuestions:
environment = Environment(undefined=StrictUndefined) environment = Environment(undefined=StrictUndefined)
system_prompt = environment.from_string(get_settings().pr_questions_prompt.system).render(variables) system_prompt = environment.from_string(get_settings().pr_questions_prompt.system).render(variables)
user_prompt = environment.from_string(get_settings().pr_questions_prompt.user).render(variables) user_prompt = environment.from_string(get_settings().pr_questions_prompt.user).render(variables)
response, finish_reason = await self.ai_handler.chat_completion(model=model, temperature=0.2, if 'img_path' in variables:
system=system_prompt, user=user_prompt) img_path = self.vars['img_path']
response, finish_reason = await self.ai_handler.chat_completion(model=model, temperature=0.2,
system=system_prompt, user=user_prompt,
img_path=img_path)
else:
response, finish_reason = await self.ai_handler.chat_completion(model=model, temperature=0.2,
system=system_prompt, user=user_prompt)
return response return response
def _prepare_pr_answer(self) -> str: def _prepare_pr_answer(self) -> str:
answer_str = f"Question: {self.question_str}\n\n" answer_str = f"### **Ask**❓\n{self.question_str}\n\n"
answer_str += f"Answer:\n{self.prediction.strip()}\n\n" answer_str += f"### **Answer:**\n{self.prediction.strip()}\n\n"
return answer_str return answer_str

View File

@ -8,7 +8,8 @@ from pr_agent.algo.ai_handlers.base_ai_handler import BaseAiHandler
from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
from pr_agent.algo.token_handler import TokenHandler from pr_agent.algo.token_handler import TokenHandler
from pr_agent.algo.utils import convert_to_markdown, load_yaml, ModelType from pr_agent.algo.utils import convert_to_markdown, github_action_output, load_yaml, ModelType, \
show_relevant_configurations
from pr_agent.config_loader import get_settings from pr_agent.config_loader import get_settings
from pr_agent.git_providers import get_git_provider from pr_agent.git_providers import get_git_provider
from pr_agent.git_providers.git_provider import IncrementalPR, get_main_pr_language from pr_agent.git_providers.git_provider import IncrementalPR, get_main_pr_language
@ -46,6 +47,8 @@ class PRReviewer:
if self.is_answer and not self.git_provider.is_supported("get_issue_comments"): if self.is_answer and not self.git_provider.is_supported("get_issue_comments"):
raise Exception(f"Answer mode is not supported for {get_settings().config.git_provider} for now") raise Exception(f"Answer mode is not supported for {get_settings().config.git_provider} for now")
self.ai_handler = ai_handler() self.ai_handler = ai_handler()
self.ai_handler.main_pr_language = self.main_language
self.patches_diff = None self.patches_diff = None
self.prediction = None self.prediction = None
@ -56,10 +59,11 @@ class PRReviewer:
"description": self.git_provider.get_pr_description(), "description": self.git_provider.get_pr_description(),
"language": self.main_language, "language": self.main_language,
"diff": "", # empty diff for initial calculation "diff": "", # empty diff for initial calculation
"num_pr_files": self.git_provider.get_num_of_files(),
"require_score": get_settings().pr_reviewer.require_score_review, "require_score": get_settings().pr_reviewer.require_score_review,
"require_tests": get_settings().pr_reviewer.require_tests_review, "require_tests": get_settings().pr_reviewer.require_tests_review,
"require_focused": get_settings().pr_reviewer.require_focused_review,
"require_estimate_effort_to_review": get_settings().pr_reviewer.require_estimate_effort_to_review, "require_estimate_effort_to_review": get_settings().pr_reviewer.require_estimate_effort_to_review,
'require_can_be_split_review': get_settings().pr_reviewer.require_can_be_split_review,
'num_code_suggestions': get_settings().pr_reviewer.num_code_suggestions, 'num_code_suggestions': get_settings().pr_reviewer.num_code_suggestions,
'question_str': question_str, 'question_str': question_str,
'answer_str': answer_str, 'answer_str': answer_str,
@ -121,7 +125,7 @@ class PRReviewer:
if get_settings().config.publish_output: if get_settings().config.publish_output:
self.git_provider.publish_comment("Preparing review...", is_temporary=True) self.git_provider.publish_comment("Preparing review...", is_temporary=True)
await retry_with_fallback_models(self._prepare_prediction, model_type=ModelType.TURBO) await retry_with_fallback_models(self._prepare_prediction)
if not self.prediction: if not self.prediction:
self.git_provider.remove_initial_comment() self.git_provider.remove_initial_comment()
return None return None
@ -134,7 +138,7 @@ class PRReviewer:
if get_settings().pr_reviewer.persistent_comment and not self.incremental.is_incremental: if get_settings().pr_reviewer.persistent_comment and not self.incremental.is_incremental:
final_update_message = get_settings().pr_reviewer.final_update_message final_update_message = get_settings().pr_reviewer.final_update_message
self.git_provider.publish_persistent_comment(pr_review, self.git_provider.publish_persistent_comment(pr_review,
initial_header="## PR Review", initial_header="## PR Review 🔍",
update_header=True, update_header=True,
final_update_message=final_update_message, ) final_update_message=final_update_message, )
else: else:
@ -189,6 +193,7 @@ class PRReviewer:
data = load_yaml(self.prediction.strip(), data = load_yaml(self.prediction.strip(),
keys_fix_yaml=["estimated_effort_to_review_[1-5]:", "security_concerns:", "possible_issues:", keys_fix_yaml=["estimated_effort_to_review_[1-5]:", "security_concerns:", "possible_issues:",
"relevant_file:", "relevant_line:", "suggestion:"]) "relevant_file:", "relevant_line:", "suggestion:"])
github_action_output(data, 'review')
if 'code_feedback' in data: if 'code_feedback' in data:
code_feedback = data['code_feedback'] code_feedback = data['code_feedback']
@ -230,10 +235,14 @@ class PRReviewer:
# Add help text if gfm_markdown is supported # Add help text if gfm_markdown is supported
if self.git_provider.is_supported("gfm_markdown") and get_settings().pr_reviewer.enable_help_text: if self.git_provider.is_supported("gfm_markdown") and get_settings().pr_reviewer.enable_help_text:
markdown_text += "<hr>\n\n<details> <summary><strong>✨ Review tool usage guide:</strong></summary><hr> \n\n" markdown_text += "<hr>\n\n<details> <summary><strong>💡 Tool usage guide:</strong></summary><hr> \n\n"
markdown_text += HelpMessage.get_review_usage_guide() markdown_text += HelpMessage.get_review_usage_guide()
markdown_text += "\n</details>\n" markdown_text += "\n</details>\n"
# Output the relevant configurations if enabled
if get_settings().get('config', {}).get('output_relevant_configurations', False):
markdown_text += show_relevant_configurations(relevant_section='pr_reviewer')
# Add custom labels from the review prediction (effort, security) # Add custom labels from the review prediction (effort, security)
self.set_review_labels(data) self.set_review_labels(data)
@ -354,6 +363,9 @@ class PRReviewer:
return True return True
def set_review_labels(self, data): def set_review_labels(self, data):
if not get_settings().config.publish_output:
return
if (get_settings().pr_reviewer.enable_review_labels_security or if (get_settings().pr_reviewer.enable_review_labels_security or
get_settings().pr_reviewer.enable_review_labels_effort): get_settings().pr_reviewer.enable_review_labels_effort):
try: try:
@ -369,17 +381,22 @@ class PRReviewer:
if security_concerns_bool: if security_concerns_bool:
review_labels.append('Possible security concern') review_labels.append('Possible security concern')
current_labels = self.git_provider.get_pr_labels() current_labels = self.git_provider.get_pr_labels(update=True)
if not current_labels:
current_labels = []
get_logger().debug(f"Current labels:\n{current_labels}")
if current_labels: if current_labels:
current_labels_filtered = [label for label in current_labels if current_labels_filtered = [label for label in current_labels if
not label.lower().startswith('review effort [1-5]:') and not label.lower().startswith( not label.lower().startswith('review effort [1-5]:') and not label.lower().startswith(
'possible security concern')] 'possible security concern')]
else: else:
current_labels_filtered = [] current_labels_filtered = []
if current_labels or review_labels: new_labels = review_labels + current_labels_filtered
get_logger().debug(f"Current labels:\n{current_labels}") if (current_labels or review_labels) and sorted(new_labels) != sorted(current_labels):
get_logger().info(f"Setting review labels:\n{review_labels + current_labels_filtered}") get_logger().info(f"Setting review labels:\n{review_labels + current_labels_filtered}")
self.git_provider.publish_labels(review_labels + current_labels_filtered) self.git_provider.publish_labels(new_labels)
else:
get_logger().info(f"Review labels are already set:\n{review_labels + current_labels_filtered}")
except Exception as e: except Exception as e:
get_logger().error(f"Failed to set review labels, error: {e}") get_logger().error(f"Failed to set review labels, error: {e}")

View File

@ -3,9 +3,6 @@ from enum import Enum
from typing import List from typing import List
import openai import openai
import pandas as pd
import pinecone
from pinecone_datasets import Dataset, DatasetMetadata
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from pr_agent.algo import MAX_TOKENS from pr_agent.algo import MAX_TOKENS
@ -36,6 +33,12 @@ class PRSimilarIssue:
index_name = self.index_name = "codium-ai-pr-agent-issues" index_name = self.index_name = "codium-ai-pr-agent-issues"
if get_settings().pr_similar_issue.vectordb == "pinecone": if get_settings().pr_similar_issue.vectordb == "pinecone":
try:
import pinecone
from pinecone_datasets import Dataset, DatasetMetadata
import pandas as pd
except:
raise Exception("Please install 'pinecone' and 'pinecone_datasets' to use pinecone as vectordb")
# assuming pinecone api key and environment are set in secrets file # assuming pinecone api key and environment are set in secrets file
try: try:
api_key = get_settings().pinecone.api_key api_key = get_settings().pinecone.api_key
@ -107,7 +110,10 @@ class PRSimilarIssue:
get_logger().info('No new issues to update') get_logger().info('No new issues to update')
elif get_settings().pr_similar_issue.vectordb == "lancedb": elif get_settings().pr_similar_issue.vectordb == "lancedb":
import lancedb # import lancedb only if needed try:
import lancedb # import lancedb only if needed
except:
raise Exception("Please install lancedb to use lancedb as vectordb")
self.db = lancedb.connect(get_settings().lancedb.uri) self.db = lancedb.connect(get_settings().lancedb.uri)
self.table = None self.table = None

View File

@ -8,7 +8,7 @@ from pr_agent.algo.ai_handlers.base_ai_handler import BaseAiHandler
from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
from pr_agent.algo.token_handler import TokenHandler from pr_agent.algo.token_handler import TokenHandler
from pr_agent.algo.utils import ModelType from pr_agent.algo.utils import ModelType, show_relevant_configurations
from pr_agent.config_loader import get_settings from pr_agent.config_loader import get_settings
from pr_agent.git_providers import get_git_provider, GithubProvider from pr_agent.git_providers import get_git_provider, GithubProvider
from pr_agent.git_providers.git_provider import get_main_pr_language from pr_agent.git_providers.git_provider import get_main_pr_language
@ -26,7 +26,10 @@ class PRUpdateChangelog:
) )
self.commit_changelog = get_settings().pr_update_changelog.push_changelog_changes self.commit_changelog = get_settings().pr_update_changelog.push_changelog_changes
self._get_changlog_file() # self.changelog_file_str self._get_changlog_file() # self.changelog_file_str
self.ai_handler = ai_handler() self.ai_handler = ai_handler()
self.ai_handler.main_pr_language = self.main_language
self.patches_diff = None self.patches_diff = None
self.prediction = None self.prediction = None
self.cli_mode = cli_mode self.cli_mode = cli_mode
@ -71,6 +74,11 @@ class PRUpdateChangelog:
await retry_with_fallback_models(self._prepare_prediction, model_type=ModelType.TURBO) await retry_with_fallback_models(self._prepare_prediction, model_type=ModelType.TURBO)
new_file_content, answer = self._prepare_changelog_update() new_file_content, answer = self._prepare_changelog_update()
# Output the relevant configurations if enabled
if get_settings().get('config', {}).get('output_relevant_configurations', False):
answer += show_relevant_configurations(relevant_section='pr_update_changelog')
get_logger().debug(f"PR output", artifact=answer) get_logger().debug(f"PR output", artifact=answer)
if get_settings().config.publish_output: if get_settings().config.publish_output:
@ -78,7 +86,7 @@ class PRUpdateChangelog:
if self.commit_changelog: if self.commit_changelog:
self._push_changelog_update(new_file_content, answer) self._push_changelog_update(new_file_content, answer)
else: else:
self.git_provider.publish_comment(f"**Changelog updates:**\n\n{answer}") self.git_provider.publish_comment(f"**Changelog updates:** 🔄\n\n{answer}")
async def _prepare_prediction(self, model: str): async def _prepare_prediction(self, model: str):
self.patches_diff = get_pr_diff(self.git_provider, self.token_handler, model) self.patches_diff = get_pr_diff(self.git_provider, self.token_handler, model)
@ -138,7 +146,7 @@ class PRUpdateChangelog:
self.git_provider.pr.create_review(commit=last_commit_id, comments=[d]) self.git_provider.pr.create_review(commit=last_commit_id, comments=[d])
except Exception: except Exception:
# we can't create a review for some reason, let's just publish a comment # we can't create a review for some reason, let's just publish a comment
self.git_provider.publish_comment(f"**Changelog updates:**\n\n{answer}") self.git_provider.publish_comment(f"**Changelog updates: 🔄**\n\n{answer}")
def _get_default_changelog(self): def _get_default_changelog(self):
example_changelog = \ example_changelog = \

View File

@ -3,44 +3,44 @@ requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta" build-backend = "setuptools.build_meta"
[project] [project]
name = "pr_agent" name = "pr-agent"
version = "0.0.1" version = "0.2.1"
authors = [{name= "CodiumAI", email = "tal.r@codium.ai"}]
authors = [
{name = "Itamar Friedman", email = "itamar.f@codium.ai"},
]
maintainers = [ maintainers = [
{name = "Ori Kotek", email = "ori.k@codium.ai"},
{name = "Tal Ridnik", email = "tal.r@codium.ai"}, {name = "Tal Ridnik", email = "tal.r@codium.ai"},
{name = "Ori Kotek", email = "ori.k@codium.ai"},
{name = "Hussam Lawen", email = "hussam.l@codium.ai"}, {name = "Hussam Lawen", email = "hussam.l@codium.ai"},
{name = "Sagi Medina", email = "sagi.m@codium.ai"}
] ]
description = "CodiumAI PR-Agent is an open-source tool to automatically analyze a pull request and provide several types of feedback"
description = "CodiumAI PR-Agent aims to help efficiently review and handle pull requests, by providing AI feedbacks and suggestions."
readme = "README.md" readme = "README.md"
requires-python = ">=3.10" requires-python = ">=3.10"
keywords = ["ai", "tool", "developer", "review", "agent"] keywords = ["AI", "Agents", "Pull Request", "Automation", "Code Review"]
license = {file = "LICENSE", name = "Apache 2.0 License"} license = {name = "Apache 2.0", file = "LICENSE"}
classifiers = [ classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers", "Intended Audience :: Developers",
"Operating System :: Independent",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
] ]
dynamic = ["dependencies"] dynamic = ["dependencies"]
[tool.setuptools.dynamic] [tool.setuptools.dynamic]
dependencies = {file = ["requirements.txt"]} dependencies = {file = ["requirements.txt"]}
[project.urls] [project.urls]
"Homepage" = "https://github.com/Codium-ai/pr-agent" "Homepage" = "https://github.com/Codium-ai/pr-agent"
"Documentation" = "https://pr-agent-docs.codium.ai/"
[tool.setuptools] [tool.setuptools]
include-package-data = false include-package-data = true
license-files = ["LICENSE"] license-files = ["LICENSE"]
[tool.setuptools.packages.find] [tool.setuptools.packages.find]
where = ["."] where = ["."]
include = ["pr_agent"] include = ["pr_agent*"] # include pr_agent and any sub-packages it finds under it.
[project.scripts] [project.scripts]
pr-agent = "pr_agent.cli:run" pr-agent = "pr_agent.cli:run"

View File

@ -1 +1,3 @@
pytest==7.4.0 pytest==7.4.0
poetry
twine

View File

@ -9,21 +9,23 @@ GitPython==3.1.32
google-cloud-aiplatform==1.35.0 google-cloud-aiplatform==1.35.0
google-cloud-storage==2.10.0 google-cloud-storage==2.10.0
Jinja2==3.1.2 Jinja2==3.1.2
litellm==1.29.1 litellm==1.31.10
loguru==0.7.2 loguru==0.7.2
msrest==0.7.1 msrest==0.7.1
openai==1.13.3 openai==1.13.3
pinecone-client
pinecone-datasets @ git+https://github.com/mrT23/pinecone-datasets.git@main
lancedb==0.5.1
pytest==7.4.0 pytest==7.4.0
PyGithub==1.59.* PyGithub==1.59.*
PyYAML==6.0.1 PyYAML==6.0.1
python-gitlab==3.15.0 python-gitlab==3.15.0
retry==0.9.2 retry==0.9.2
starlette-context==0.3.6 starlette-context==0.3.6
tiktoken==0.5.2 tiktoken==0.7.0
ujson==5.8.0 ujson==5.8.0
uvicorn==0.22.0 uvicorn==0.22.0
tenacity==8.2.3 tenacity==8.2.3
# langchain==0.0.349 # uncomment this to support language LangChainOpenAIHandler # Uncomment the following lines to enable the 'similar issue' tool
# pinecone-client
# pinecone-datasets @ git+https://github.com/mrT23/pinecone-datasets.git@main
# lancedb==0.5.1
# uncomment this to support language LangChainOpenAIHandler
# langchain==0.0.349

View File

@ -15,5 +15,5 @@ class TestClipTokens:
max_tokens = 10 max_tokens = 10
result = clip_tokens(text, max_tokens) result = clip_tokens(text, max_tokens)
expected_results = 'line1\nline2\nline3\nli...(truncated)' expected_results = 'line1\nline2\nline3\nli\n...(truncated)'
assert result == expected_results assert result == expected_results

View File

@ -52,7 +52,7 @@ class TestConvertToMarkdown:
'suggestion': "Consider raising an exception or logging a warning when 'pr_url' attribute is not found. This can help in debugging issues related to the absence of 'pr_url' in instances where it's expected. [important]\n", 'suggestion': "Consider raising an exception or logging a warning when 'pr_url' attribute is not found. This can help in debugging issues related to the absence of 'pr_url' in instances where it's expected. [important]\n",
'relevant_line': '[return ""](https://github.com/Codium-ai/pr-agent-pro/pull/102/files#diff-52d45f12b836f77ed1aef86e972e65404634ea4e2a6083fb71a9b0f9bb9e062fR199)'}]} 'relevant_line': '[return ""](https://github.com/Codium-ai/pr-agent-pro/pull/102/files#diff-52d45f12b836f77ed1aef86e972e65404634ea4e2a6083fb71a9b0f9bb9e062fR199)'}]}
expected_output = '## PR Review\n\n<table>\n<tr>\n<tr><td> ⏱️&nbsp;<strong>Estimated&nbsp;effort&nbsp;to&nbsp;review [1-5]</strong></td><td>\n\n1, because the changes are minimal and straightforward, focusing on a single functionality addition.\n\n\n</td></tr>\n<tr><td> 🧪&nbsp;<strong>Relevant tests</strong></td><td>\n\nNo\n\n\n</td></tr>\n<tr><td> 🔍&nbsp;<strong>Possible issues</strong></td><td>\n\nNo\n\n</td></tr>\n<tr><td> 🔒&nbsp;<strong>Security concerns</strong></td><td>\n\nNo\n\n</td></tr>\n</table>\n\n\n<details><summary> <strong>Code feedback:</strong></summary>\n\n<hr><table><tr><td>relevant file</td><td>pr_agent/git_providers/git_provider.py\n</td></tr><tr><td>suggestion &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td><td>\n\n<strong>\n\nConsider raising an exception or logging a warning when \'pr_url\' attribute is not found. This can help in debugging issues related to the absence of \'pr_url\' in instances where it\'s expected. [important]\n\n</strong>\n</td></tr><tr><td>relevant line</td><td><a href=\'https://github.com/Codium-ai/pr-agent-pro/pull/102/files#diff-52d45f12b836f77ed1aef86e972e65404634ea4e2a6083fb71a9b0f9bb9e062fR199\'>return ""</a></td></tr></table><hr>\n\n</details>' expected_output = '## PR Review 🔍\n\n<table>\n<tr>\n<tr><td> ⏱️&nbsp;<strong>Estimated&nbsp;effort&nbsp;to&nbsp;review [1-5]</strong></td><td>\n\n1, because the changes are minimal and straightforward, focusing on a single functionality addition.\n\n\n</td></tr>\n<tr><td> 🧪&nbsp;<strong>Relevant tests</strong></td><td>\n\nNo\n\n\n</td></tr>\n<tr><td> &nbsp;<strong>Possible issues</strong></td><td>\n\nNo\n\n</td></tr>\n<tr><td> 🔒&nbsp;<strong>Security concerns</strong></td><td>\n\nNo\n\n</td></tr>\n</table>\n\n\n<details><summary> <strong>Code feedback:</strong></summary>\n\n<hr><table><tr><td>relevant file</td><td>pr_agent/git_providers/git_provider.py\n</td></tr><tr><td>suggestion &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td><td>\n\n<strong>\n\nConsider raising an exception or logging a warning when \'pr_url\' attribute is not found. This can help in debugging issues related to the absence of \'pr_url\' in instances where it\'s expected. [important]\n\n</strong>\n</td></tr><tr><td>relevant line</td><td><a href=\'https://github.com/Codium-ai/pr-agent-pro/pull/102/files#diff-52d45f12b836f77ed1aef86e972e65404634ea4e2a6083fb71a9b0f9bb9e062fR199\'>return ""</a></td></tr></table><hr>\n\n</details>'
assert convert_to_markdown(input_data).strip() == expected_output.strip() assert convert_to_markdown(input_data).strip() == expected_output.strip()

View File

@ -0,0 +1,50 @@
import os
import json
from pr_agent.algo.utils import get_settings, github_action_output
class TestGitHubOutput:
def test_github_action_output_enabled(self, monkeypatch, tmp_path):
get_settings().set('GITHUB_ACTION_CONFIG.ENABLE_OUTPUT', True)
monkeypatch.setenv('GITHUB_OUTPUT', str(tmp_path / 'output'))
output_data = {'key1': {'value1': 1, 'value2': 2}}
key_name = 'key1'
github_action_output(output_data, key_name)
with open(str(tmp_path / 'output'), 'r') as f:
env_value = f.read()
actual_key = env_value.split('=')[0]
actual_data = json.loads(env_value.split('=')[1])
assert actual_key == key_name
assert actual_data == output_data[key_name]
def test_github_action_output_disabled(self, monkeypatch, tmp_path):
get_settings().set('GITHUB_ACTION_CONFIG.ENABLE_OUTPUT', False)
monkeypatch.setenv('GITHUB_OUTPUT', str(tmp_path / 'output'))
output_data = {'key1': {'value1': 1, 'value2': 2}}
key_name = 'key1'
github_action_output(output_data, key_name)
assert not os.path.exists(str(tmp_path / 'output'))
def test_github_action_output_notset(self, monkeypatch, tmp_path):
# not set config
monkeypatch.setenv('GITHUB_OUTPUT', str(tmp_path / 'output'))
output_data = {'key1': {'value1': 1, 'value2': 2}}
key_name = 'key1'
github_action_output(output_data, key_name)
assert not os.path.exists(str(tmp_path / 'output'))
def test_github_action_output_error_case(self, monkeypatch, tmp_path):
monkeypatch.setenv('GITHUB_OUTPUT', str(tmp_path / 'output'))
output_data = None # invalid data
key_name = 'key1'
github_action_output(output_data, key_name)
assert not os.path.exists(str(tmp_path / 'output'))