-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/cog 971 preparing swe bench run #424
Changes from 18 commits
56cc223
9604d95
6177d04
16155f0
06e8d22
c163e35
36407b2
6f7bbb0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Answer the question using the provided context. If the provided context is not connected to the question, just answer "The provided knowledge base does not contain the answer to the question". Be as brief as possible. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
The question is: `{{ question }}` | ||
and here is the context provided with a set of relationships from a knowledge graph separated by \n---\n each represented as node1 -- relation -- node2 triplet: `{{ context }}` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
I need you to solve this issue by looking at the provided edges retrieved from a knowledge graph and | ||
generate a single patch file that I can apply directly to this repository using git apply. | ||
Please respond with a single patch file in the following format. | ||
You are a senior software engineer. I need you to solve this issue by looking at the provided context and | ||
generate a single patch file that I can apply directly to this repository using git apply. | ||
Additionally, please make sure that you provide code only with correct syntax and | ||
you apply the patch on the relevant files (together with their path that you can try to find out from the github issue). Don't change the names of existing | ||
functions or classes, as they may be referenced from other code. | ||
Please respond only with a single patch file in the following format without adding any additional context or string. |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -8,27 +8,35 @@ | |||||||||||||||||||||||||||||||||||||||||
from cognee.modules.users.methods import get_default_user | ||||||||||||||||||||||||||||||||||||||||||
from cognee.modules.users.models import User | ||||||||||||||||||||||||||||||||||||||||||
from cognee.shared.utils import send_telemetry | ||||||||||||||||||||||||||||||||||||||||||
from cognee.api.v1.search import SearchType | ||||||||||||||||||||||||||||||||||||||||||
from cognee.api.v1.search.search_v2 import search | ||||||||||||||||||||||||||||||||||||||||||
from cognee.infrastructure.llm.get_llm_client import get_llm_client | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
async def code_description_to_code_part_search(query: str, user: User = None, top_k=2) -> list: | ||||||||||||||||||||||||||||||||||||||||||
async def code_description_to_code_part_search( | ||||||||||||||||||||||||||||||||||||||||||
query: str, include_docs=False, user: User = None, top_k=5 | ||||||||||||||||||||||||||||||||||||||||||
) -> list: | ||||||||||||||||||||||||||||||||||||||||||
if user is None: | ||||||||||||||||||||||||||||||||||||||||||
user = await get_default_user() | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
if user is None: | ||||||||||||||||||||||||||||||||||||||||||
raise PermissionError("No user found in the system. Please create a user.") | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
retrieved_codeparts = await code_description_to_code_part(query, user, top_k) | ||||||||||||||||||||||||||||||||||||||||||
retrieved_codeparts = await code_description_to_code_part(query, user, top_k, include_docs) | ||||||||||||||||||||||||||||||||||||||||||
return retrieved_codeparts | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
async def code_description_to_code_part(query: str, user: User, top_k: int) -> List[str]: | ||||||||||||||||||||||||||||||||||||||||||
async def code_description_to_code_part( | ||||||||||||||||||||||||||||||||||||||||||
query: str, user: User, top_k: int, include_docs: bool = False | ||||||||||||||||||||||||||||||||||||||||||
) -> List[str]: | ||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||
Maps a code description query to relevant code parts using a CodeGraph pipeline. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Args: | ||||||||||||||||||||||||||||||||||||||||||
query (str): The search query describing the code parts. | ||||||||||||||||||||||||||||||||||||||||||
user (User): The user performing the search. | ||||||||||||||||||||||||||||||||||||||||||
top_k (int): Number of codegraph descriptions to match ( num of corresponding codeparts will be higher) | ||||||||||||||||||||||||||||||||||||||||||
include_docs(bool): Boolean showing whether we have the docs in the graph or not | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Returns: | ||||||||||||||||||||||||||||||||||||||||||
Set[str]: A set of unique code parts matching the query. | ||||||||||||||||||||||||||||||||||||||||||
|
@@ -55,21 +63,49 @@ async def code_description_to_code_part(query: str, user: User, top_k: int) -> L | |||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||
results = await vector_engine.search("code_summary_text", query_text=query, limit=top_k) | ||||||||||||||||||||||||||||||||||||||||||
if not results: | ||||||||||||||||||||||||||||||||||||||||||
if include_docs: | ||||||||||||||||||||||||||||||||||||||||||
search_results = await search(SearchType.INSIGHTS, query_text=query) | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
concatenated_descriptions = " ".join( | ||||||||||||||||||||||||||||||||||||||||||
obj["description"] | ||||||||||||||||||||||||||||||||||||||||||
for tpl in search_results | ||||||||||||||||||||||||||||||||||||||||||
for obj in tpl | ||||||||||||||||||||||||||||||||||||||||||
if isinstance(obj, dict) and "description" in obj | ||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
llm_client = get_llm_client() | ||||||||||||||||||||||||||||||||||||||||||
context_from_documents = await llm_client.acreate_structured_output( | ||||||||||||||||||||||||||||||||||||||||||
text_input=f"The retrieved context from documents" | ||||||||||||||||||||||||||||||||||||||||||
f" is {concatenated_descriptions}.", | ||||||||||||||||||||||||||||||||||||||||||
system_prompt="You are a Senior Software Engineer, summarize the context from documents" | ||||||||||||||||||||||||||||||||||||||||||
f" in a way that it is gonna be provided next to codeparts as context" | ||||||||||||||||||||||||||||||||||||||||||
f" while trying to solve this github issue connected to the project: {query}]", | ||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+80
to
+82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix the syntax error and improve the system prompt There is an unmatched closing bracket Apply this diff to fix the syntax error: - f" while trying to solve this github issue connected to the project: {query}]",
+ f" while trying to solve this GitHub issue connected to the project: {query}", Revised system_prompt = (
"You are a Senior Software Engineer. "
"Summarize the context from the documents so it can be provided "
"as context alongside code parts while trying to solve "
f"the following GitHub issue connected to the project: {query}"
) |
||||||||||||||||||||||||||||||||||||||||||
response_model=str, | ||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
code_summaries = await vector_engine.search( | ||||||||||||||||||||||||||||||||||||||||||
"code_summary_text", query_text=query, limit=top_k | ||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||
if not code_summaries: | ||||||||||||||||||||||||||||||||||||||||||
logging.warning("No results found for query: '%s' by user: %s", query, user.id) | ||||||||||||||||||||||||||||||||||||||||||
return [] | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
memory_fragment = CogneeGraph() | ||||||||||||||||||||||||||||||||||||||||||
await memory_fragment.project_graph_from_db( | ||||||||||||||||||||||||||||||||||||||||||
graph_engine, | ||||||||||||||||||||||||||||||||||||||||||
node_properties_to_project=["id", "type", "text", "source_code"], | ||||||||||||||||||||||||||||||||||||||||||
node_properties_to_project=[ | ||||||||||||||||||||||||||||||||||||||||||
"id", | ||||||||||||||||||||||||||||||||||||||||||
"type", | ||||||||||||||||||||||||||||||||||||||||||
"text", | ||||||||||||||||||||||||||||||||||||||||||
"source_code", | ||||||||||||||||||||||||||||||||||||||||||
"pydantic_type", | ||||||||||||||||||||||||||||||||||||||||||
], | ||||||||||||||||||||||||||||||||||||||||||
edge_properties_to_project=["relationship_name"], | ||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
code_pieces_to_return = set() | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
for node in results: | ||||||||||||||||||||||||||||||||||||||||||
for node in code_summaries: | ||||||||||||||||||||||||||||||||||||||||||
node_id = str(node.id) | ||||||||||||||||||||||||||||||||||||||||||
node_to_search_from = memory_fragment.get_node(node_id) | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
|
@@ -78,9 +114,16 @@ async def code_description_to_code_part(query: str, user: User, top_k: int) -> L | |||||||||||||||||||||||||||||||||||||||||
continue | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
for code_file in node_to_search_from.get_skeleton_neighbours(): | ||||||||||||||||||||||||||||||||||||||||||
for code_file_edge in code_file.get_skeleton_edges(): | ||||||||||||||||||||||||||||||||||||||||||
if code_file_edge.get_attribute("relationship_name") == "contains": | ||||||||||||||||||||||||||||||||||||||||||
code_pieces_to_return.add(code_file_edge.get_destination_node()) | ||||||||||||||||||||||||||||||||||||||||||
if code_file.get_attribute("pydantic_type") == "SourceCodeChunk": | ||||||||||||||||||||||||||||||||||||||||||
for code_file_edge in code_file.get_skeleton_edges(): | ||||||||||||||||||||||||||||||||||||||||||
if code_file_edge.get_attribute("relationship_name") == "code_chunk_of": | ||||||||||||||||||||||||||||||||||||||||||
code_pieces_to_return.add(code_file_edge.get_destination_node()) | ||||||||||||||||||||||||||||||||||||||||||
elif code_file.get_attribute("pydantic_type") == "CodePart": | ||||||||||||||||||||||||||||||||||||||||||
code_pieces_to_return.add(code_file) | ||||||||||||||||||||||||||||||||||||||||||
elif code_file.get_attribute("pydantic_type") == "CodeFile": | ||||||||||||||||||||||||||||||||||||||||||
for code_file_edge in code_file.get_skeleton_edges(): | ||||||||||||||||||||||||||||||||||||||||||
if code_file_edge.get_attribute("relationship_name") == "contains": | ||||||||||||||||||||||||||||||||||||||||||
code_pieces_to_return.add(code_file_edge.get_destination_node()) | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
logging.info( | ||||||||||||||||||||||||||||||||||||||||||
"Search completed for user: %s, query: '%s'. Found %d code pieces.", | ||||||||||||||||||||||||||||||||||||||||||
|
@@ -89,7 +132,14 @@ async def code_description_to_code_part(query: str, user: User, top_k: int) -> L | |||||||||||||||||||||||||||||||||||||||||
len(code_pieces_to_return), | ||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
return list(code_pieces_to_return) | ||||||||||||||||||||||||||||||||||||||||||
context = "" | ||||||||||||||||||||||||||||||||||||||||||
for code_piece in code_pieces_to_return: | ||||||||||||||||||||||||||||||||||||||||||
context = context + code_piece.get_attribute("source_code") | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
if include_docs: | ||||||||||||||||||||||||||||||||||||||||||
context = context_from_documents + context | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
return context | ||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+135
to
+142
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve code concatenation for better memory efficiency and readability The current string concatenation approach could be inefficient for large code bases and lacks separation between different code pieces. - context = ""
- for code_piece in code_pieces_to_return:
- context = context + code_piece.get_attribute("source_code")
+ code_pieces_content = [
+ code_piece.get_attribute("source_code")
+ for code_piece in code_pieces_to_return
+ ]
+
+ # Add separator between code pieces for better readability
+ context = "\n\n---\n\n".join(code_pieces_content)
if include_docs:
- context = context_from_documents + context
+ context = f"{context_from_documents}\n\n---\n\n{context}" 📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: ruff format[warning] File requires formatting with Ruff formatter |
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
except Exception as exec_error: | ||||||||||||||||||||||||||||||||||||||||||
logging.error( | ||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
from .query_completion import query_completion | ||
from .graph_query_completion import graph_query_completion |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from cognee.infrastructure.databases.vector import get_vector_engine | ||
from cognee.tasks.completion.exceptions import NoRelevantDataFound | ||
from cognee.infrastructure.llm.get_llm_client import get_llm_client | ||
from cognee.infrastructure.llm.prompts import read_query_prompt, render_prompt | ||
from cognee.modules.retrieval.brute_force_triplet_search import brute_force_triplet_search | ||
|
||
|
||
def retrieved_edges_to_string(retrieved_edges: list) -> str: | ||
edge_strings = [] | ||
for edge in retrieved_edges: | ||
node1_string = edge.node1.attributes.get("text") or edge.node1.attributes.get("name") | ||
node2_string = edge.node2.attributes.get("text") or edge.node2.attributes.get("name") | ||
edge_string = edge.attributes["relationship_type"] | ||
edge_str = f"{node1_string} -- {edge_string} -- {node2_string}" | ||
edge_strings.append(edge_str) | ||
return "\n---\n".join(edge_strings) | ||
|
||
|
||
async def graph_query_completion(query: str) -> list: | ||
""" | ||
Parameters: | ||
- query (str): The query string to compute. | ||
|
||
Returns: | ||
- list: Answer to the query. | ||
""" | ||
found_triplets = await brute_force_triplet_search(query, top_k=5) | ||
|
||
if len(found_triplets) == 0: | ||
raise NoRelevantDataFound | ||
|
||
args = { | ||
"question": query, | ||
"context": retrieved_edges_to_string(found_triplets), | ||
} | ||
user_prompt = render_prompt("graph_context_for_question.txt", args) | ||
system_prompt = read_query_prompt("answer_simple_question_restricted.txt") | ||
|
||
llm_client = get_llm_client() | ||
computed_answer = await llm_client.acreate_structured_output( | ||
text_input=user_prompt, | ||
system_prompt=system_prompt, | ||
response_model=str, | ||
) | ||
|
||
return [computed_answer] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for search results
The search results processing lacks error handling and validation. Consider adding checks for empty results and proper error handling.
🧰 Tools
🪛 GitHub Actions: ruff format
[warning] File requires formatting with Ruff formatter