Merge pull request #1434 from Codium-ai/tr/ollama

Tr/ollama
This commit is contained in:
Tal
2025-01-02 16:26:46 +02:00
committed by GitHub
10 changed files with 153 additions and 35 deletions

View File

@ -30,50 +30,36 @@ model="" # the OpenAI model you've deployed on Azure (e.g. gpt-4o)
fallback_models=["..."] fallback_models=["..."]
``` ```
### Hugging Face ### Ollama
**Local** You can run models locally through either [VLLM](https://docs.litellm.ai/docs/providers/vllm) or [Ollama](https://docs.litellm.ai/docs/providers/ollama)
You can run Hugging Face models locally through either [VLLM](https://docs.litellm.ai/docs/providers/vllm) or [Ollama](https://docs.litellm.ai/docs/providers/ollama)
E.g. to use a new Hugging Face model locally via Ollama, set: E.g. to use a new model locally via Ollama, set in `.secrets.toml` or in a configuration file:
``` ```
[__init__.py] [config]
MAX_TOKENS = { model = "ollama/qwen2.5-coder:32b"
"model-name-on-ollama": <max_tokens> fallback_models=["ollama/qwen2.5-coder:32b"]
} custom_model_max_tokens=128000 # set the maximal input tokens for the model
e.g. duplicate_examples=true # will duplicate the examples in the prompt, to help the model to output structured output
MAX_TOKENS={
...,
"ollama/llama2": 4096
}
[ollama]
[config] # in configuration.toml api_base = "http://localhost:11434" # or whatever port you're running Ollama on
model = "ollama/llama2"
fallback_models=["ollama/llama2"]
[ollama] # in .secrets.toml
api_base = ... # the base url for your Hugging Face inference endpoint
# e.g. if running Ollama locally, you may use:
api_base = "http://localhost:11434/"
``` ```
### Inference Endpoints !!! note "Local models vs commercial models"
Qodo Merge is compatible with almost any AI model, but analyzing complex code repositories and pull requests requires a model specifically optimized for code analysis.
Commercial models such as GPT-4, Claude Sonnet, and Gemini have demonstrated robust capabilities in generating structured output for code analysis tasks with large input. In contrast, most open-source models currently available (as of January 2025) face challenges with these complex tasks.
Based on our testing, local open-source models are suitable for experimentation and learning purposes, but they are not suitable for production-level code analysis tasks.
Hence, for production workflows and real-world usage, we recommend using commercial models.
### Hugging Face Inference Endpoints
To use a new model with Hugging Face Inference Endpoints, for example, set: To use a new model with Hugging Face Inference Endpoints, for example, set:
``` ```
[__init__.py]
MAX_TOKENS = {
"model-name-on-huggingface": <max_tokens>
}
e.g.
MAX_TOKENS={
...,
"meta-llama/Llama-2-7b-chat-hf": 4096
}
[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"
fallback_models=["huggingface/meta-llama/Llama-2-7b-chat-hf"] fallback_models=["huggingface/meta-llama/Llama-2-7b-chat-hf"]
custom_model_max_tokens=... # set the maximal input tokens for the model
[huggingface] # in .secrets.toml [huggingface] # in .secrets.toml
key = ... # your Hugging Face api key key = ... # your Hugging Face api key

View File

@ -12,7 +12,6 @@ global_settings = Dynaconf(
envvar_prefix=False, envvar_prefix=False,
merge_enabled=True, merge_enabled=True,
settings_files=[join(current_dir, f) for f in [ settings_files=[join(current_dir, f) for f in [
"settings/.secrets.toml",
"settings/configuration.toml", "settings/configuration.toml",
"settings/ignore.toml", "settings/ignore.toml",
"settings/language_extensions.toml", "settings/language_extensions.toml",
@ -29,6 +28,7 @@ global_settings = Dynaconf(
"settings/pr_add_docs.toml", "settings/pr_add_docs.toml",
"settings/custom_labels.toml", "settings/custom_labels.toml",
"settings/pr_help_prompts.toml", "settings/pr_help_prompts.toml",
"settings/.secrets.toml",
"settings_prod/.secrets.toml", "settings_prod/.secrets.toml",
]] ]]
) )

View File

@ -34,6 +34,7 @@ ai_disclaimer_title="" # Pro feature, title for a collapsible disclaimer to AI
ai_disclaimer="" # Pro feature, full text for the AI disclaimer ai_disclaimer="" # Pro feature, full text for the AI disclaimer
output_relevant_configurations=false output_relevant_configurations=false
large_patch_policy = "clip" # "clip", "skip" large_patch_policy = "clip" # "clip", "skip"
duplicate_prompt_examples = false
# seed # seed
seed=-1 # set positive value to fix the seed (and ensure temperature=0) seed=-1 # set positive value to fix the seed (and ensure temperature=0)
temperature=0.2 temperature=0.2

View File

@ -125,6 +125,30 @@ The PR Diff:
{{ diff_no_line_numbers|trim }} {{ diff_no_line_numbers|trim }}
====== ======
{%- if duplicate_prompt_examples %}
Example output:
```yaml
code_suggestions:
- relevant_file: |
src/file1.py
language: |
python
suggestion_content: |
...
existing_code: |
...
improved_code: |
...
one_sentence_summary: |
...
label: |
...
```
(replace '...' with actual content)
{%- endif %}
Response (should be a valid YAML, and nothing else): Response (should be a valid YAML, and nothing else):
```yaml ```yaml

View File

@ -122,6 +122,25 @@ Below are {{ num_code_suggestions }} AI-generated code suggestions for enhancing
====== ======
{%- if duplicate_prompt_examples %}
Example output:
```yaml
code_suggestions:
- suggestion_summary: |
...
relevant_file: "..."
relevant_lines_start: ...
relevant_lines_end: ...
suggestion_score: ...
why: |
...
- ...
```
(replace '...' with actual content)
{%- endif %}
Response (should be a valid YAML, and nothing else): Response (should be a valid YAML, and nothing else):
```yaml ```yaml
""" """

View File

@ -130,6 +130,37 @@ The PR Git Diff:
Note that lines in the diff body are prefixed with a symbol that represents the type of change: '-' for deletions, '+' for additions, and ' ' (a space) for unchanged lines. Note that lines in the diff body are prefixed with a symbol that represents the type of change: '-' for deletions, '+' for additions, and ' ' (a space) for unchanged lines.
{%- if duplicate_prompt_examples %}
Example output:
```yaml
type:
- Bug fix
- Refactoring
- ...
description: |
...
title: |
...
{%- if enable_semantic_files_types %}
pr_files:
- filename: |
...
{%- if include_file_summary_changes %}
changes_summary: |
...
{%- endif %}
changes_title: |
...
label: |
label_key_1
...
{%- endif %}
```
(replace '...' with the actual values)
{%- endif %}
Response (should be a valid YAML, and nothing else): Response (should be a valid YAML, and nothing else):
```yaml ```yaml

View File

@ -221,6 +221,59 @@ The PR code diff:
====== ======
{%- if duplicate_prompt_examples %}
Example output:
```yaml
review:
{%- if related_tickets %}
ticket_compliance_check:
- ticket_url: |
...
ticket_requirements: |
...
fully_compliant_requirements: |
...
not_compliant_requirements: |
...
overall_compliance_level: |
...
{%- endif %}
{%- if require_estimate_effort_to_review %}
estimated_effort_to_review_[1-5]: |
3
{%- endif %}
{%- if require_score %}
score: 89
{%- endif %}
relevant_tests: |
No
key_issues_to_review:
- relevant_file: |
...
issue_header: |
...
issue_content: |
...
start_line: ...
end_line: ...
- ...
security_concerns: |
No
{%- if require_can_be_split_review %}
can_be_split:
- relevant_files:
- ...
- ...
title: ...
- ...
{%- endif %}
```
(replace '...' with the actual values)
{%- endif %}
Response (should be a valid YAML, and nothing else): Response (should be a valid YAML, and nothing else):
```yaml ```yaml
""" """

View File

@ -81,6 +81,7 @@ class PRCodeSuggestions:
"relevant_best_practices": "", "relevant_best_practices": "",
"is_ai_metadata": get_settings().get("config.enable_ai_metadata", False), "is_ai_metadata": get_settings().get("config.enable_ai_metadata", False),
"focus_only_on_problems": get_settings().get("pr_code_suggestions.focus_only_on_problems", False), "focus_only_on_problems": get_settings().get("pr_code_suggestions.focus_only_on_problems", False),
'duplicate_prompt_examples': get_settings().config.get('duplicate_prompt_examples', False),
} }
self.pr_code_suggestions_prompt_system = get_settings().pr_code_suggestions_prompt.system self.pr_code_suggestions_prompt_system = get_settings().pr_code_suggestions_prompt.system
@ -830,7 +831,8 @@ class PRCodeSuggestions:
"diff": patches_diff, "diff": patches_diff,
'num_code_suggestions': len(suggestion_list), 'num_code_suggestions': len(suggestion_list),
'prev_suggestions_str': prev_suggestions_str, 'prev_suggestions_str': prev_suggestions_str,
"is_ai_metadata": get_settings().get("config.enable_ai_metadata", False)} "is_ai_metadata": get_settings().get("config.enable_ai_metadata", False),
'duplicate_prompt_examples': get_settings().config.get('duplicate_prompt_examples', False)}
environment = Environment(undefined=StrictUndefined) environment = Environment(undefined=StrictUndefined)
if dedicated_prompt: if dedicated_prompt:

View File

@ -71,7 +71,8 @@ class PRDescription:
"custom_labels_class": "", # will be filled if necessary in 'set_custom_labels' function "custom_labels_class": "", # will be filled if necessary in 'set_custom_labels' function
"enable_semantic_files_types": get_settings().pr_description.enable_semantic_files_types, "enable_semantic_files_types": get_settings().pr_description.enable_semantic_files_types,
"related_tickets": "", "related_tickets": "",
"include_file_summary_changes": len(self.git_provider.get_diff_files()) <= self.COLLAPSIBLE_FILE_LIST_THRESHOLD "include_file_summary_changes": len(self.git_provider.get_diff_files()) <= self.COLLAPSIBLE_FILE_LIST_THRESHOLD,
'duplicate_prompt_examples': get_settings().config.get('duplicate_prompt_examples', False),
} }
self.user_description = self.git_provider.get_user_description() self.user_description = self.git_provider.get_user_description()

View File

@ -94,6 +94,7 @@ class PRReviewer:
"enable_custom_labels": get_settings().config.enable_custom_labels, "enable_custom_labels": get_settings().config.enable_custom_labels,
"is_ai_metadata": get_settings().get("config.enable_ai_metadata", False), "is_ai_metadata": get_settings().get("config.enable_ai_metadata", False),
"related_tickets": get_settings().get('related_tickets', []), "related_tickets": get_settings().get('related_tickets', []),
'duplicate_prompt_examples': get_settings().config.get('duplicate_prompt_examples', False),
} }
self.token_handler = TokenHandler( self.token_handler = TokenHandler(