bioguider 0.2.12__py3-none-any.whl → 0.2.13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bioguider might be problematic. Click here for more details.
- bioguider/agents/agent_task.py +8 -4
- bioguider/agents/agent_tools.py +17 -14
- bioguider/agents/agent_utils.py +40 -4
- bioguider/agents/collection_observe_step.py +7 -5
- bioguider/agents/collection_plan_step.py +9 -7
- bioguider/agents/collection_task.py +15 -5
- bioguider/agents/collection_task_utils.py +46 -15
- bioguider/agents/dockergeneration_task.py +1 -1
- bioguider/agents/evaluation_installation_task.py +29 -7
- bioguider/agents/evaluation_readme_task.py +26 -4
- bioguider/agents/evaluation_submission_requirements_task.py +153 -0
- bioguider/agents/evaluation_task.py +19 -6
- bioguider/agents/identification_observe_step.py +7 -1
- bioguider/agents/identification_plan_step.py +6 -1
- bioguider/agents/identification_task.py +23 -4
- bioguider/agents/identification_task_utils.py +2 -0
- bioguider/agents/prompt_utils.py +44 -4
- bioguider/managers/evaluation_manager.py +38 -46
- bioguider/utils/constants.py +2 -0
- {bioguider-0.2.12.dist-info → bioguider-0.2.13.dist-info}/METADATA +1 -1
- {bioguider-0.2.12.dist-info → bioguider-0.2.13.dist-info}/RECORD +23 -22
- {bioguider-0.2.12.dist-info → bioguider-0.2.13.dist-info}/LICENSE +0 -0
- {bioguider-0.2.12.dist-info → bioguider-0.2.13.dist-info}/WHEEL +0 -0
bioguider/agents/agent_task.py
CHANGED
|
@@ -13,7 +13,12 @@ class AgentTask(ABC):
|
|
|
13
13
|
A class representing a step in an agent's process.
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
-
def __init__(
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
llm: BaseChatOpenAI,
|
|
19
|
+
step_callback: Callable | None = None,
|
|
20
|
+
summarized_files_db: SummarizedFilesDb | None = None,
|
|
21
|
+
):
|
|
17
22
|
"""
|
|
18
23
|
Initialize the AgentStep with a language model and a callback function.
|
|
19
24
|
|
|
@@ -23,7 +28,7 @@ class AgentTask(ABC):
|
|
|
23
28
|
"""
|
|
24
29
|
self.llm = llm
|
|
25
30
|
self.step_callback = step_callback
|
|
26
|
-
self.
|
|
31
|
+
self.summarized_files_db = summarized_files_db
|
|
27
32
|
self.graph: CompiledGraph | None = None
|
|
28
33
|
|
|
29
34
|
def _print_step(
|
|
@@ -45,7 +50,7 @@ class AgentTask(ABC):
|
|
|
45
50
|
token_usage=token_usage,
|
|
46
51
|
)
|
|
47
52
|
|
|
48
|
-
def compile(self, repo_path: str, gitignore_path: str,
|
|
53
|
+
def compile(self, repo_path: str, gitignore_path: str, **kwargs):
|
|
49
54
|
"""
|
|
50
55
|
Compile the agent step with the given repository and gitignore paths.
|
|
51
56
|
|
|
@@ -55,7 +60,6 @@ class AgentTask(ABC):
|
|
|
55
60
|
**kwargs: derived class may pass more arguments to implmented _compile(), that is,
|
|
56
61
|
what **kwargs is depends on derived class
|
|
57
62
|
"""
|
|
58
|
-
self.summary_file_db = db
|
|
59
63
|
self._compile(repo_path, gitignore_path, **kwargs)
|
|
60
64
|
|
|
61
65
|
@abstractmethod
|
bioguider/agents/agent_tools.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import logging
|
|
2
3
|
from typing import Callable
|
|
3
4
|
from markdownify import markdownify as md
|
|
4
5
|
from langchain_openai.chat_models.base import BaseChatOpenAI
|
|
@@ -7,6 +8,8 @@ from bioguider.utils.file_utils import get_file_type
|
|
|
7
8
|
from bioguider.agents.agent_utils import read_directory, read_file, summarize_file
|
|
8
9
|
from bioguider.rag.data_pipeline import count_tokens
|
|
9
10
|
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
10
13
|
class agent_tool:
|
|
11
14
|
def __init__(
|
|
12
15
|
self,
|
|
@@ -53,19 +56,12 @@ Returns:
|
|
|
53
56
|
class summarize_file_tool(agent_tool):
|
|
54
57
|
""" Read a file and generate a summary according to a specified prompt.
|
|
55
58
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
Path to the file to read.
|
|
60
|
-
summarize_prompt : str, optional
|
|
61
|
-
Instruction guiding the summarization focus (default is "N/A").
|
|
62
|
-
Use this to emphasize specific aspects of the content.
|
|
59
|
+
Args:
|
|
60
|
+
file_path str: required. The file path to read.
|
|
61
|
+
summarize_prompt str: optional. A string instruction guiding the summarization focus (default is "N/A"). Use this to emphasize specific aspects of the content.
|
|
63
62
|
|
|
64
|
-
Returns
|
|
65
|
-
|
|
66
|
-
str or None
|
|
67
|
-
A summarized version of the file content.
|
|
68
|
-
Returns None if the file does not exist or cannot be read.
|
|
63
|
+
Returns:
|
|
64
|
+
str or None: A summarized version of the file content. Returns None if the file does not exist or cannot be read.
|
|
69
65
|
"""
|
|
70
66
|
def __init__(
|
|
71
67
|
self,
|
|
@@ -124,8 +120,15 @@ Returns
|
|
|
124
120
|
if summarized_content is not None:
|
|
125
121
|
return f"summarized content of file {file_path}: " + summarized_content
|
|
126
122
|
|
|
127
|
-
|
|
128
|
-
|
|
123
|
+
try:
|
|
124
|
+
file_content = read_file(abs_file_path)
|
|
125
|
+
file_content = file_content.replace("{", "{{").replace("}", "}}")
|
|
126
|
+
except UnicodeDecodeError as e:
|
|
127
|
+
logger.error(str(e))
|
|
128
|
+
return f"{file_path} is a binary, can't be summarized."
|
|
129
|
+
except Exception as e:
|
|
130
|
+
logger.error(str(e))
|
|
131
|
+
return f"Failed to read {file_path}."
|
|
129
132
|
summarized_content, token_usage = summarize_file(
|
|
130
133
|
self.llm, abs_file_path, file_content, self.detailed_level,
|
|
131
134
|
summary_instructions=self.summarize_instruction,
|
bioguider/agents/agent_utils.py
CHANGED
|
@@ -16,11 +16,12 @@ from langchain.tools import BaseTool
|
|
|
16
16
|
from langchain.schema import AgentAction, AgentFinish
|
|
17
17
|
from langchain.agents import AgentOutputParser
|
|
18
18
|
from langgraph.prebuilt import create_react_agent
|
|
19
|
+
from langchain_community.callbacks.openai_info import OpenAICallbackHandler
|
|
19
20
|
import logging
|
|
20
21
|
|
|
21
22
|
from pydantic import BaseModel, Field
|
|
22
23
|
|
|
23
|
-
from bioguider.utils.constants import DEFAULT_TOKEN_USAGE
|
|
24
|
+
from bioguider.utils.constants import DEFAULT_TOKEN_USAGE, MAX_FILE_LENGTH, MAX_SENTENCE_NUM
|
|
24
25
|
from bioguider.utils.file_utils import get_file_type
|
|
25
26
|
from ..utils.gitignore_checker import GitignoreChecker
|
|
26
27
|
from ..database.summarized_file_db import SummarizedFilesDb
|
|
@@ -178,8 +179,7 @@ Here is the file content:
|
|
|
178
179
|
Now, let's start to summarize.
|
|
179
180
|
""")
|
|
180
181
|
|
|
181
|
-
|
|
182
|
-
MAX_SENTENCE_NUM=20
|
|
182
|
+
|
|
183
183
|
def summarize_file(
|
|
184
184
|
llm: BaseChatOpenAI,
|
|
185
185
|
name: str,
|
|
@@ -379,6 +379,20 @@ def escape_braces(text: str) -> str:
|
|
|
379
379
|
text = re.sub(r'(?<!{){(?!{)', '{{', text)
|
|
380
380
|
return text
|
|
381
381
|
|
|
382
|
+
STRING_TO_OBJECT_SYSTEM_PROMPT = """
|
|
383
|
+
You are an expert to understand data. You will be provided a text, and your task is to extracted structured data from the provided text.
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
### **Instructions**
|
|
388
|
+
1. If no structured data can be extracted, return None
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
### **Input Text**
|
|
393
|
+
{input_text}
|
|
394
|
+
"""
|
|
395
|
+
|
|
382
396
|
def try_parse_json_object(json_obj: str) -> dict | None:
|
|
383
397
|
json_obj = json_obj.strip()
|
|
384
398
|
|
|
@@ -406,4 +420,26 @@ def try_parse_json_object(json_obj: str) -> dict | None:
|
|
|
406
420
|
return None
|
|
407
421
|
except Exception as e:
|
|
408
422
|
logger.error(e)
|
|
409
|
-
return None
|
|
423
|
+
return None
|
|
424
|
+
|
|
425
|
+
def try_parse_with_llm(llm: BaseChatOpenAI, input_text: str, schema: any):
|
|
426
|
+
system_prompt = ChatPromptTemplate.from_template(
|
|
427
|
+
STRING_TO_OBJECT_SYSTEM_PROMPT
|
|
428
|
+
).format(input_text=input_text)
|
|
429
|
+
prompt = ChatPromptTemplate.from_messages([
|
|
430
|
+
("system", system_prompt)
|
|
431
|
+
])
|
|
432
|
+
agent = prompt | llm.with_structured_output(schema)
|
|
433
|
+
callback_handler = OpenAICallbackHandler()
|
|
434
|
+
|
|
435
|
+
try:
|
|
436
|
+
res = agent.invoke(
|
|
437
|
+
input={},
|
|
438
|
+
config={
|
|
439
|
+
"callbacks": [callback_handler],
|
|
440
|
+
},
|
|
441
|
+
)
|
|
442
|
+
return res, vars(callback_handler)
|
|
443
|
+
except Exception as e:
|
|
444
|
+
logger.error(e)
|
|
445
|
+
return None
|
|
@@ -5,7 +5,7 @@ from langchain_openai.chat_models.base import BaseChatOpenAI
|
|
|
5
5
|
from langchain_core.prompts import ChatPromptTemplate
|
|
6
6
|
from bioguider.agents.agent_utils import ObservationResult
|
|
7
7
|
from bioguider.agents.collection_task_utils import CollectionWorkflowState
|
|
8
|
-
from bioguider.agents.common_agent_2step import CommonAgentTwoSteps
|
|
8
|
+
from bioguider.agents.common_agent_2step import CommonAgentTwoChainSteps, CommonAgentTwoSteps
|
|
9
9
|
from bioguider.agents.peo_common_step import PEOCommonStep
|
|
10
10
|
from bioguider.agents.prompt_utils import COLLECTION_GOAL, COLLECTION_PROMPTS
|
|
11
11
|
|
|
@@ -34,11 +34,13 @@ Here is the 2-level file structure of the repository (`f` = file, `d` = director
|
|
|
34
34
|
|
|
35
35
|
* Provide your reasoning under **Analysis**
|
|
36
36
|
* Then list all relevant files and folders under **FinalAnswer**
|
|
37
|
+
* **FinalAnswer** format must exactly match this format:
|
|
38
|
+
**FinalAnswer**: {{"final_answer": [<file path>, <file path>, <file path>, ...]}}
|
|
37
39
|
* Be sure to include the **full relative paths** with respect to the repository root.
|
|
38
|
-
* Your answer **must
|
|
40
|
+
* Your answer **must exactly match the follwing format** (note: no JSON code block, no additional comments), **do not** make up anything:
|
|
39
41
|
|
|
40
42
|
```
|
|
41
|
-
**Analysis**: your analysis here
|
|
43
|
+
**Analysis**: your analysis here
|
|
42
44
|
**FinalAnswer**: {{"final_answer": ["path/to/file1", "path/to/file2", ...]}}
|
|
43
45
|
```
|
|
44
46
|
4. If you believe **more files still need to be collected**:
|
|
@@ -80,8 +82,8 @@ class CollectionObserveStep(PEOCommonStep):
|
|
|
80
82
|
repo_structure = self.repo_structure
|
|
81
83
|
intermediate_steps = self._build_intermediate_steps(state)
|
|
82
84
|
prompt = ChatPromptTemplate.from_template(COLLECTION_OBSERVE_SYSTEM_PROMPT)
|
|
83
|
-
important_instructions = "N/A" if "
|
|
84
|
-
else collection_item["
|
|
85
|
+
important_instructions = "N/A" if "observe_important_instructions" not in collection_item or len(collection_item["observe_important_instructions"]) == 0 \
|
|
86
|
+
else collection_item["observe_important_instructions"]
|
|
85
87
|
return prompt.format(
|
|
86
88
|
goal_item_desc=goal_item_desc,
|
|
87
89
|
related_file_description=collection_item["related_file_description"],
|
|
@@ -8,7 +8,7 @@ from bioguider.agents.agent_utils import (
|
|
|
8
8
|
PlanAgentResultJsonSchema,
|
|
9
9
|
PlanAgentResult,
|
|
10
10
|
)
|
|
11
|
-
from bioguider.agents.common_agent_2step import CommonAgentTwoSteps
|
|
11
|
+
from bioguider.agents.common_agent_2step import CommonAgentTwoChainSteps, CommonAgentTwoSteps
|
|
12
12
|
from bioguider.agents.peo_common_step import PEOCommonStep
|
|
13
13
|
from bioguider.agents.collection_task_utils import CollectionWorkflowState
|
|
14
14
|
from bioguider.agents.prompt_utils import COLLECTION_GOAL, COLLECTION_PROMPTS
|
|
@@ -57,7 +57,9 @@ Here are the results from previous steps:
|
|
|
57
57
|
|
|
58
58
|
3. You may use the `read_directory` tool to explore directory contents, but avoid using it in the first step unless necessary.
|
|
59
59
|
|
|
60
|
-
4.
|
|
60
|
+
4. Your plan can only use the above tools, **do not** make up any tools not in the above tools list.
|
|
61
|
+
|
|
62
|
+
5. Your planned step input file or input directory must come from the above repository files structure, **do not** make up file name or directory name.
|
|
61
63
|
|
|
62
64
|
---
|
|
63
65
|
|
|
@@ -65,12 +67,12 @@ Here are the results from previous steps:
|
|
|
65
67
|
{important_instructions}
|
|
66
68
|
|
|
67
69
|
### **Output Format**
|
|
68
|
-
Your plan
|
|
70
|
+
Your plan **must exactly match** a sequence of steps in the following format, **do not** make up anything:
|
|
69
71
|
|
|
70
|
-
Step: <tool name> # Tool name must be one of {tool_names}
|
|
72
|
+
Step: <tool name> # Tool name **must be one** of {tool_names}
|
|
71
73
|
Step Input: <file or directory name>
|
|
72
74
|
|
|
73
|
-
Step: <tool name>
|
|
75
|
+
Step: <tool name> # Tool name **must be one** of {tool_names}
|
|
74
76
|
Step Input: <file or directory name>
|
|
75
77
|
...
|
|
76
78
|
""")
|
|
@@ -105,8 +107,8 @@ class CollectionPlanStep(PEOCommonStep):
|
|
|
105
107
|
step_analysis, step_thoughts = self._build_intermediate_analysis_and_thoughts(state)
|
|
106
108
|
goal = ChatPromptTemplate.from_template(COLLECTION_GOAL).format(goal_item=collection_item["goal_item"])
|
|
107
109
|
related_file_description = collection_item["related_file_description"]
|
|
108
|
-
important_instructions="N/A" if "
|
|
109
|
-
else collection_item["
|
|
110
|
+
important_instructions="N/A" if "plan_important_instructions" not in collection_item or len(collection_item["plan_important_instructions"]) == 0 \
|
|
111
|
+
else collection_item["plan_important_instructions"]
|
|
110
112
|
tool_names, tools_desc = get_tool_names_and_descriptions(self.custom_tools)
|
|
111
113
|
system_prompt = COLLECTION_PLAN_SYSTEM_PROMPT.format(
|
|
112
114
|
goal=goal,
|
|
@@ -50,9 +50,12 @@ class CollectionTask(AgentTask):
|
|
|
50
50
|
def __init__(
|
|
51
51
|
self,
|
|
52
52
|
llm: BaseChatOpenAI,
|
|
53
|
-
step_callback: Callable | None = None
|
|
53
|
+
step_callback: Callable | None = None,
|
|
54
|
+
summarize_instruction: str | None = "N/A",
|
|
55
|
+
summarized_files_db: SummarizedFilesDb | None = None,
|
|
56
|
+
provided_files: list[str] | None = None,
|
|
54
57
|
):
|
|
55
|
-
super().__init__(llm, step_callback)
|
|
58
|
+
super().__init__(llm, step_callback, summarized_files_db=summarized_files_db)
|
|
56
59
|
self.repo_path: str | None = None
|
|
57
60
|
self.gitignore_path: str | None = None
|
|
58
61
|
self.repo_structure: str | None = None
|
|
@@ -60,6 +63,8 @@ class CollectionTask(AgentTask):
|
|
|
60
63
|
self.steps: list[PEOCommonStep] = []
|
|
61
64
|
self.tools: list[any] | None = None
|
|
62
65
|
self.custom_tools: list[Tool] | None = None
|
|
66
|
+
self.summarize_instruction = summarize_instruction
|
|
67
|
+
self.provided_files = provided_files
|
|
63
68
|
|
|
64
69
|
def _prepare_tools(self, related_file_goal_item_desc):
|
|
65
70
|
tool_rd = read_directory_tool(repo_path=self.repo_path)
|
|
@@ -67,7 +72,8 @@ class CollectionTask(AgentTask):
|
|
|
67
72
|
llm=self.llm,
|
|
68
73
|
repo_path=self.repo_path,
|
|
69
74
|
output_callback=self.step_callback,
|
|
70
|
-
db=self.
|
|
75
|
+
db=self.summarized_files_db,
|
|
76
|
+
summaize_instruction=self.summarize_instruction,
|
|
71
77
|
)
|
|
72
78
|
tool_rf = read_file_tool(repo_path=self.repo_path)
|
|
73
79
|
tool_cf = check_file_related_tool(
|
|
@@ -75,6 +81,8 @@ class CollectionTask(AgentTask):
|
|
|
75
81
|
repo_path=self.repo_path,
|
|
76
82
|
goal_item_desc=related_file_goal_item_desc,
|
|
77
83
|
output_callback=self.step_callback,
|
|
84
|
+
summarize_instruction=self.summarize_instruction,
|
|
85
|
+
summarized_files_db=self.summarized_files_db,
|
|
78
86
|
)
|
|
79
87
|
self.tools = [tool_rd, tool_sum, tool_rf, tool_cf]
|
|
80
88
|
self.custom_tools = [
|
|
@@ -99,13 +107,15 @@ class CollectionTask(AgentTask):
|
|
|
99
107
|
description=tool_cf.__class__.__doc__,
|
|
100
108
|
),
|
|
101
109
|
]
|
|
102
|
-
self.custom_tools.append(CustomPythonAstREPLTool())
|
|
110
|
+
# self.custom_tools.append(CustomPythonAstREPLTool())
|
|
103
111
|
|
|
104
112
|
def _initialize(self):
|
|
105
113
|
# initialize the 2-level file structure of the repo
|
|
106
114
|
if not os.path.exists(self.repo_path):
|
|
107
115
|
raise ValueError(f"Repository path {self.repo_path} does not exist.")
|
|
108
|
-
files =
|
|
116
|
+
files = self.provided_files
|
|
117
|
+
if files is None:
|
|
118
|
+
files = read_directory(self.repo_path, os.path.join(self.repo_path, ".gitignore"))
|
|
109
119
|
file_pairs = [(f, get_file_type(os.path.join(self.repo_path, f)).value) for f in files]
|
|
110
120
|
self.repo_structure = ""
|
|
111
121
|
for f, f_type in file_pairs:
|
|
@@ -4,13 +4,17 @@ from langchain.prompts import ChatPromptTemplate
|
|
|
4
4
|
from langchain_openai.chat_models.base import BaseChatOpenAI
|
|
5
5
|
from langchain_core.messages import AIMessage
|
|
6
6
|
from pydantic import BaseModel, Field
|
|
7
|
+
import logging
|
|
7
8
|
|
|
8
9
|
from bioguider.agents.agent_tools import agent_tool
|
|
9
10
|
from bioguider.agents.agent_utils import read_file, summarize_file
|
|
10
11
|
from bioguider.agents.peo_common_step import PEOWorkflowState
|
|
11
12
|
from bioguider.agents.common_agent import CommonAgent
|
|
12
13
|
from bioguider.agents.common_agent_2step import CommonAgentTwoSteps
|
|
14
|
+
from bioguider.database.summarized_file_db import SummarizedFilesDb
|
|
15
|
+
from bioguider.utils.constants import MAX_FILE_LENGTH
|
|
13
16
|
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
14
18
|
|
|
15
19
|
class CollectionWorkflowState(TypedDict):
|
|
16
20
|
llm: Optional[BaseChatOpenAI]
|
|
@@ -46,20 +50,22 @@ Does this file appear to contain related information?
|
|
|
46
50
|
|
|
47
51
|
---
|
|
48
52
|
|
|
49
|
-
### **Output Format:**
|
|
50
|
-
Respond with
|
|
51
|
-
|
|
53
|
+
### **Output Format:**
|
|
54
|
+
Respond with exactly two parts:
|
|
55
|
+
1. A single word: Yes or No (indicating if the file meets the goal criteria)
|
|
56
|
+
2. One brief explanatory sentence.
|
|
57
|
+
For example: Yes. This file is a compiled binary file, so, it is related to the compiled standalone file (goal item).
|
|
52
58
|
""")
|
|
53
59
|
|
|
54
60
|
class CheckFileRelatedResult(BaseModel):
|
|
55
|
-
is_related:
|
|
61
|
+
is_related: str = Field(description="A string conclusion specify if the provided file is related. The string value contains two parts:\n 1. A single word: Yes or No (indicating if the file meets the goal criteria).\n 2. One brief explanatory sentence.")
|
|
56
62
|
|
|
57
63
|
class check_file_related_tool(agent_tool):
|
|
58
64
|
""" Check if the file is related to the goal item
|
|
59
65
|
Args:
|
|
60
66
|
file_path str: file path
|
|
61
67
|
Returns:
|
|
62
|
-
|
|
68
|
+
str: A string conclusion. The string conclusion contains two parts:\n 1. A single word: Yes or No (indicating if the file meets the goal criteria).\n 2. One brief explanatory sentence.
|
|
63
69
|
"""
|
|
64
70
|
def __init__(
|
|
65
71
|
self,
|
|
@@ -67,23 +73,51 @@ Returns:
|
|
|
67
73
|
repo_path: str,
|
|
68
74
|
goal_item_desc: str,
|
|
69
75
|
output_callback: Callable | None = None,
|
|
76
|
+
summarize_instruction: str | None = None,
|
|
77
|
+
summarize_level: int | None = 6,
|
|
78
|
+
summarized_files_db: SummarizedFilesDb | None = None,
|
|
70
79
|
):
|
|
71
80
|
super().__init__(llm=llm, output_callback=output_callback)
|
|
72
81
|
self.repo_path = repo_path
|
|
73
82
|
self.goal_item_desc = goal_item_desc
|
|
83
|
+
self.summarize_instruction = summarize_instruction \
|
|
84
|
+
if summarize_instruction is not None else "N/A"
|
|
85
|
+
self.summarize_level = summarize_level
|
|
86
|
+
self.summarized_files_db = summarized_files_db
|
|
74
87
|
|
|
75
88
|
def run(self, file_path: str) -> str:
|
|
76
89
|
if not self.repo_path in file_path:
|
|
77
90
|
file_path = os.path.join(self.repo_path, file_path)
|
|
78
91
|
if not os.path.isfile(file_path):
|
|
79
92
|
return "Can't read file"
|
|
80
|
-
|
|
81
|
-
|
|
93
|
+
|
|
94
|
+
check_prompts = None
|
|
95
|
+
try:
|
|
96
|
+
file_content = read_file(file_path)
|
|
97
|
+
except UnicodeDecodeError as e:
|
|
98
|
+
logger.error(str(e))
|
|
99
|
+
check_prompts = "Can't summarize binary file, please decide according to file name and extension."
|
|
100
|
+
except Exception as e:
|
|
101
|
+
logger.error(str(e))
|
|
102
|
+
check_prompts = "Failed to summarize file, please decide according to file name and extension."
|
|
103
|
+
if check_prompts is None and file_content is None:
|
|
82
104
|
return "Failed to read file"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
105
|
+
if check_prompts is not None:
|
|
106
|
+
summarized_content = check_prompts
|
|
107
|
+
else:
|
|
108
|
+
if len(file_content) > MAX_FILE_LENGTH:
|
|
109
|
+
file_content = file_content[:MAX_FILE_LENGTH]
|
|
110
|
+
summarized_content, token_usage = summarize_file(
|
|
111
|
+
llm=self.llm,
|
|
112
|
+
name=file_path,
|
|
113
|
+
content=file_content,
|
|
114
|
+
level=self.summarize_level,
|
|
115
|
+
summary_instructions=self.summarize_instruction,
|
|
116
|
+
db=self.summarized_files_db,
|
|
117
|
+
)
|
|
118
|
+
if summarized_content is None:
|
|
119
|
+
return "Failed to summarize file"
|
|
120
|
+
self._print_token_usage(token_usage)
|
|
87
121
|
|
|
88
122
|
prompt = CHECK_FILE_RELATED_USER_PROMPT.format(
|
|
89
123
|
goal_item_desc=self.goal_item_desc,
|
|
@@ -102,8 +136,5 @@ Returns:
|
|
|
102
136
|
|
|
103
137
|
self._print_step_output(step_output=reasoning)
|
|
104
138
|
self._print_token_usage(token_usage)
|
|
105
|
-
|
|
106
|
-
return "Yes, the file is related to the goal item."
|
|
107
|
-
else:
|
|
108
|
-
return "No, the file **is not** related to the goal item."
|
|
139
|
+
return res.is_related
|
|
109
140
|
|
|
@@ -9,7 +9,8 @@ from pydantic import BaseModel, Field
|
|
|
9
9
|
from markdownify import markdownify as md
|
|
10
10
|
|
|
11
11
|
from bioguider.agents.agent_utils import read_file
|
|
12
|
-
from bioguider.agents.
|
|
12
|
+
from bioguider.agents.collection_task import CollectionTask
|
|
13
|
+
from bioguider.agents.prompt_utils import EVALUATION_INSTRUCTION, CollectionGoalItemEnum
|
|
13
14
|
from bioguider.utils.constants import DEFAULT_TOKEN_USAGE, ProjectMetadata
|
|
14
15
|
from bioguider.rag.data_pipeline import count_tokens
|
|
15
16
|
from .common_agent_2step import CommonAgentTwoSteps, CommonAgentTwoChainSteps
|
|
@@ -32,14 +33,17 @@ Your task is to analyze the provided files related to installation and generate
|
|
|
32
33
|
1. **Installation Available**: Is the installation section in document (like README.md or INSTALLATION)?
|
|
33
34
|
* Output: `Yes` or `No`
|
|
34
35
|
|
|
35
|
-
2. **Installation Tutorial**: Is the installation tutorial provided?
|
|
36
|
+
2. **Installation Tutorial**: Is the step-by-step installation tutorial provided?
|
|
36
37
|
* Ouput: `Yes` or `No`
|
|
37
38
|
|
|
38
39
|
3. **Number of required Dependencies Installation**: The number of dependencies that are required to install
|
|
39
40
|
* Output: Number
|
|
40
41
|
* Suggest specific improvements if necessary, such as missing dependencies
|
|
41
42
|
|
|
42
|
-
4. **
|
|
43
|
+
4. **Compatible Operating System**: Is the compatible operating system described?
|
|
44
|
+
* Output: `Yes` or `No`
|
|
45
|
+
|
|
46
|
+
5. **Overall Score**: Give an overall quality rating of the Installation information.
|
|
43
47
|
* Output: `Poor`, `Fair`, `Good`, or `Excellent`
|
|
44
48
|
|
|
45
49
|
---
|
|
@@ -53,6 +57,7 @@ Your final report must **exactly match** the following format. Do not add or omi
|
|
|
53
57
|
**Dependency:**
|
|
54
58
|
* number: [Number]
|
|
55
59
|
* suggestions: <suggestion to improve **dependency information** like missing dependencies
|
|
60
|
+
**Compatible Operating System:** [Yes / No]
|
|
56
61
|
**Overall Score:** [Poor / Fair / Good / Excellent]
|
|
57
62
|
|
|
58
63
|
---
|
|
@@ -113,6 +118,7 @@ class StructuredEvaluationInstallationResult(BaseModel):
|
|
|
113
118
|
install_tutorial: Optional[bool]=Field(description="A boolean value. Is the installation tutorial provided?")
|
|
114
119
|
dependency_number: Optional[int]=Field(description="A number. It is the number of dependencies that are required to install.")
|
|
115
120
|
dependency_suggestions: Optional[str]=Field(description="A string value. It is the specific improvements if necessary, such as missing dependencies")
|
|
121
|
+
compatible_os: Optional[bool]=Field(description="A boolean value. Is compatible operating system described?")
|
|
116
122
|
overall_score: Optional[str]=Field(description="A overall scroll for the installation quality, could be `Poor`, `Fair`, `Good`, or `Excellent`")
|
|
117
123
|
|
|
118
124
|
class EvaluationInstallationResult(BaseModel):
|
|
@@ -163,8 +169,9 @@ class EvaluationInstallationTask(EvaluationTask):
|
|
|
163
169
|
gitignore_path,
|
|
164
170
|
meta_data = None,
|
|
165
171
|
step_callback = None,
|
|
172
|
+
summarized_files_db = None,
|
|
166
173
|
):
|
|
167
|
-
super().__init__(llm, repo_path, gitignore_path, meta_data, step_callback)
|
|
174
|
+
super().__init__(llm, repo_path, gitignore_path, meta_data, step_callback, summarized_files_db)
|
|
168
175
|
self.evaluation_name = "Installation Evaluation"
|
|
169
176
|
|
|
170
177
|
|
|
@@ -235,7 +242,7 @@ class EvaluationInstallationTask(EvaluationTask):
|
|
|
235
242
|
}
|
|
236
243
|
return evaluation, token_usage
|
|
237
244
|
|
|
238
|
-
def _evaluate(self, files: list[str] | None = None) -> tuple[dict | None, dict]:
|
|
245
|
+
def _evaluate(self, files: list[str] | None = None) -> tuple[dict | None, dict, list[str]]:
|
|
239
246
|
evaluation, token_usage = self._free_evaluate(files)
|
|
240
247
|
structured_evaluation, structured_token_usage = self._structured_evaluate(files)
|
|
241
248
|
|
|
@@ -245,5 +252,20 @@ class EvaluationInstallationTask(EvaluationTask):
|
|
|
245
252
|
}
|
|
246
253
|
total_token_usage = increase_token_usage(token_usage, structured_token_usage)
|
|
247
254
|
|
|
248
|
-
return combined_evaluation, total_token_usage
|
|
249
|
-
|
|
255
|
+
return combined_evaluation, total_token_usage, files
|
|
256
|
+
|
|
257
|
+
def _collect_files(self):
|
|
258
|
+
task = CollectionTask(
|
|
259
|
+
llm=self.llm,
|
|
260
|
+
step_callback=self.step_callback,
|
|
261
|
+
)
|
|
262
|
+
task.compile(
|
|
263
|
+
repo_path=self.repo_path,
|
|
264
|
+
gitignore_path=Path(self.repo_path, ".gitignore"),
|
|
265
|
+
db=self.summarized_files_db,
|
|
266
|
+
goal_item=CollectionGoalItemEnum.Installation.name,
|
|
267
|
+
)
|
|
268
|
+
files = task.collect()
|
|
269
|
+
if files is None:
|
|
270
|
+
return []
|
|
271
|
+
return files
|
|
@@ -7,6 +7,7 @@ from langchain_openai.chat_models.base import BaseChatOpenAI
|
|
|
7
7
|
from pydantic import BaseModel, Field
|
|
8
8
|
|
|
9
9
|
from bioguider.agents.prompt_utils import EVALUATION_INSTRUCTION
|
|
10
|
+
from bioguider.utils.gitignore_checker import GitignoreChecker
|
|
10
11
|
|
|
11
12
|
from ..utils.pyphen_utils import PyphenReadability
|
|
12
13
|
from bioguider.agents.agent_utils import increase_token_usage, read_file, summarize_file
|
|
@@ -303,9 +304,10 @@ class EvaluationREADMETask(EvaluationTask):
|
|
|
303
304
|
repo_path: str,
|
|
304
305
|
gitignore_path: str,
|
|
305
306
|
meta_data: ProjectMetadata | None = None,
|
|
306
|
-
step_callback: Callable | None = None
|
|
307
|
+
step_callback: Callable | None = None,
|
|
308
|
+
summarized_files_db = None,
|
|
307
309
|
):
|
|
308
|
-
super().__init__(llm, repo_path, gitignore_path, meta_data, step_callback)
|
|
310
|
+
super().__init__(llm, repo_path, gitignore_path, meta_data, step_callback, summarized_files_db)
|
|
309
311
|
self.evaluation_name = "README Evaluation"
|
|
310
312
|
|
|
311
313
|
def _structured_evaluate(self, free_readme_evaluations: dict[str, dict]):
|
|
@@ -455,7 +457,7 @@ class EvaluationREADMETask(EvaluationTask):
|
|
|
455
457
|
total_token_usage = increase_token_usage(total_token_usage, token_usage)
|
|
456
458
|
return readme_evaluations, total_token_usage
|
|
457
459
|
|
|
458
|
-
def _evaluate(self, files: list[str]) -> tuple[dict, dict]:
|
|
460
|
+
def _evaluate(self, files: list[str]) -> tuple[dict, dict, list[str]]:
|
|
459
461
|
free_readme_evaluations, free_token_usage = self._free_evaluate(files)
|
|
460
462
|
structured_readme_evaluations, structured_token_usage = self._structured_evaluate(free_readme_evaluations)
|
|
461
463
|
|
|
@@ -472,6 +474,26 @@ class EvaluationREADMETask(EvaluationTask):
|
|
|
472
474
|
|
|
473
475
|
total_token_usage = increase_token_usage(free_token_usage, structured_token_usage)
|
|
474
476
|
|
|
475
|
-
return combined_evaluations, total_token_usage
|
|
477
|
+
return combined_evaluations, total_token_usage, files
|
|
476
478
|
|
|
479
|
+
def _collect_files(self):
|
|
480
|
+
"""
|
|
481
|
+
Search for a README file in the repository directory.
|
|
482
|
+
"""
|
|
483
|
+
possible_readme_files = [
|
|
484
|
+
"readme.md",
|
|
485
|
+
"readme.rst",
|
|
486
|
+
"readme.txt",
|
|
487
|
+
"readme",
|
|
488
|
+
]
|
|
489
|
+
repo_path = self.repo_path
|
|
490
|
+
gitignore_path = Path(repo_path, ".gitignore")
|
|
491
|
+
gitignore_checker = GitignoreChecker(
|
|
492
|
+
directory=repo_path, gitignore_path=gitignore_path
|
|
493
|
+
)
|
|
494
|
+
found_readme_files = gitignore_checker.check_files_and_folders(
|
|
495
|
+
check_file_cb=lambda root_dir, relative_path: Path(relative_path).name.lower() in possible_readme_files,
|
|
496
|
+
)
|
|
497
|
+
|
|
498
|
+
return found_readme_files
|
|
477
499
|
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
from bioguider.agents.agent_utils import try_parse_json_object, try_parse_with_llm
|
|
5
|
+
from bioguider.agents.evaluation_task import EvaluationTask
|
|
6
|
+
from bioguider.agents.collection_task import CollectionTask
|
|
7
|
+
from bioguider.agents.identification_task import IdentificationTask
|
|
8
|
+
from bioguider.agents.prompt_utils import CollectionGoalItemEnum
|
|
9
|
+
from bioguider.agents.evaluation_installation_task import StructuredEvaluationInstallationResult
|
|
10
|
+
from bioguider.utils.constants import DEFAULT_TOKEN_USAGE
|
|
11
|
+
|
|
12
|
+
DEMO_INSTRUCTION_GOAL = """
|
|
13
|
+
1. Identify if it provides the instructions to run on provided data
|
|
14
|
+
2. Identify if it provides the instructions to run on custom data
|
|
15
|
+
3. Identify if it provides the expected output
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
DEMO_INSTRUCTION_FINAL_ANSWER = \
|
|
19
|
+
'{{"run_on_data_instruction": <True or False>, "run_on_custom_instruction": <True or False>, "expected_output_description": <True Or False>}}'
|
|
20
|
+
|
|
21
|
+
class DemoInstructionsResult(BaseModel):
|
|
22
|
+
run_on_data_instruction: Optional[bool] = Field(description="A boolean value. Does it provide instructions on how to run on provided data?")
|
|
23
|
+
run_on_custom_instruction: Optional[bool] = Field(description="A boolean value. Does it provide instructions on how to run on custom data?")
|
|
24
|
+
expected_output_description: Optional[bool] = Field(description="A boolean value. Does it provide the description of expected output?")
|
|
25
|
+
|
|
26
|
+
class EvaluationSubmissionRequirementsTask(EvaluationTask):
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
llm,
|
|
30
|
+
repo_path,
|
|
31
|
+
gitignore_path,
|
|
32
|
+
meta_data = None,
|
|
33
|
+
step_callback = None,
|
|
34
|
+
summarized_files_db = None,
|
|
35
|
+
readme_files_evaluation: dict | None = None,
|
|
36
|
+
installation_evaluation: dict | None = None,
|
|
37
|
+
installation_files: list[str] | None = None
|
|
38
|
+
):
|
|
39
|
+
super().__init__(llm, repo_path, gitignore_path, meta_data, step_callback, summarized_files_db)
|
|
40
|
+
self.evaluation_name = "Submission Requirements Evaluation"
|
|
41
|
+
self.readme_files_evaluation = readme_files_evaluation
|
|
42
|
+
self.installation_evaluation = installation_evaluation
|
|
43
|
+
self.installation_files = installation_files
|
|
44
|
+
|
|
45
|
+
def _collect_software_package_content(self):
|
|
46
|
+
collection_task = CollectionTask(
|
|
47
|
+
llm = self.llm,
|
|
48
|
+
step_callback=self.step_callback,
|
|
49
|
+
summarize_instruction="We are collecting compiled standalone files, source code files and example data files.",
|
|
50
|
+
summarized_files_db=self.summarized_files_db,
|
|
51
|
+
)
|
|
52
|
+
collection_task.compile(
|
|
53
|
+
repo_path=self.repo_path,
|
|
54
|
+
gitignore_path=self.gitignore_path,
|
|
55
|
+
db=self.summarized_files_db,
|
|
56
|
+
goal_item=CollectionGoalItemEnum.SoftwarePackageContent.name,
|
|
57
|
+
)
|
|
58
|
+
files = collection_task.collect()
|
|
59
|
+
|
|
60
|
+
return files
|
|
61
|
+
|
|
62
|
+
def _evaluate_software_package_content(self):
|
|
63
|
+
files = self._collect_software_package_content()
|
|
64
|
+
if len(files) == 3:
|
|
65
|
+
return {
|
|
66
|
+
"compiled_standalone_software": files[0].strip().lower() != "n/a",
|
|
67
|
+
"source_code": files[1].strip().lower() != "n/a",
|
|
68
|
+
"demo_dataset": files[2].strip().lower() != "n/a",
|
|
69
|
+
}, files
|
|
70
|
+
else:
|
|
71
|
+
return {
|
|
72
|
+
"compiled_standalone_software": False,
|
|
73
|
+
"source_code": False,
|
|
74
|
+
"demo_dataset": False,
|
|
75
|
+
}, files
|
|
76
|
+
|
|
77
|
+
def _evaluatie_demo_instructions(self):
|
|
78
|
+
readme_files = [f for f in self.readme_files_evaluation.keys() \
|
|
79
|
+
if self.readme_files_evaluation[f]["evaluation"]["project_level"]]
|
|
80
|
+
installation_files = self.installation_files if self.installation_files is not None else []
|
|
81
|
+
provided_files = readme_files + installation_files
|
|
82
|
+
provided_files = provided_files if len(provided_files) > 0 else None
|
|
83
|
+
identify_task = IdentificationTask(
|
|
84
|
+
llm=self.llm,
|
|
85
|
+
step_callback=self.step_callback,
|
|
86
|
+
summarized_files_db=self.summarized_files_db,
|
|
87
|
+
provided_files=provided_files
|
|
88
|
+
)
|
|
89
|
+
identify_task.compile(
|
|
90
|
+
repo_path=self.repo_path,
|
|
91
|
+
gitignore_path=self.gitignore_path,
|
|
92
|
+
)
|
|
93
|
+
final_answer = identify_task.identify_customize_goal(
|
|
94
|
+
goal="demo instructions",
|
|
95
|
+
final_answer_example=DEMO_INSTRUCTION_FINAL_ANSWER,
|
|
96
|
+
)
|
|
97
|
+
final_answer = final_answer["final_answer"] \
|
|
98
|
+
if final_answer is not None and "final_answer" in final_answer else final_answer
|
|
99
|
+
parsed_obj = self._parse_demo_instruction_result(final_answer)
|
|
100
|
+
return parsed_obj, provided_files
|
|
101
|
+
|
|
102
|
+
def _parse_demo_instruction_result(self, result: str | dict):
|
|
103
|
+
if isinstance(result, dict):
|
|
104
|
+
return result
|
|
105
|
+
obj = try_parse_json_object(result)
|
|
106
|
+
if obj is None:
|
|
107
|
+
obj, token_usage = try_parse_with_llm(
|
|
108
|
+
llm=self.llm,
|
|
109
|
+
input_text=result,
|
|
110
|
+
schema=DemoInstructionsResult,
|
|
111
|
+
)
|
|
112
|
+
obj = vars(obj) if obj is not None else obj
|
|
113
|
+
self.print_step(token_usage=token_usage)
|
|
114
|
+
self.print_step(step_output=str(obj))
|
|
115
|
+
|
|
116
|
+
return obj
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _combine_evaluation(
|
|
120
|
+
self,
|
|
121
|
+
software_evaluation: dict,
|
|
122
|
+
demo_evaluation: dict,
|
|
123
|
+
):
|
|
124
|
+
readme_files = [f for f in self.readme_files_evaluation.keys() \
|
|
125
|
+
if self.readme_files_evaluation[f]["evaluation"]["project_level"]]
|
|
126
|
+
structured_install_evaluation: StructuredEvaluationInstallationResult = \
|
|
127
|
+
self.installation_evaluation["structured_evaluation"]
|
|
128
|
+
software_dependency = structured_install_evaluation.dependency_number > 0
|
|
129
|
+
install_tutorial = structured_install_evaluation.install_tutorial
|
|
130
|
+
license = any([self.readme_files_evaluation[f]["structured_evaluation"].license_score for f in readme_files])
|
|
131
|
+
return {
|
|
132
|
+
**software_evaluation,
|
|
133
|
+
**demo_evaluation,
|
|
134
|
+
"complete_readme": len(readme_files) > 0,
|
|
135
|
+
"software_dependency": software_dependency,
|
|
136
|
+
"install_tutorial": install_tutorial,
|
|
137
|
+
"license": license,
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
def _evaluate(self, files):
|
|
141
|
+
|
|
142
|
+
software_evaluation, software_files = self._evaluate_software_package_content()
|
|
143
|
+
demo_evaluation, demo_files = self._evaluatie_demo_instructions()
|
|
144
|
+
files = list(set(software_files + demo_files))
|
|
145
|
+
|
|
146
|
+
return self._combine_evaluation(software_evaluation, demo_evaluation), {**DEFAULT_TOKEN_USAGE}, files
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _collect_files(self):
|
|
150
|
+
return []
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
@@ -9,6 +9,7 @@ from langchain_openai.chat_models.base import BaseChatOpenAI
|
|
|
9
9
|
|
|
10
10
|
from bioguider.agents.agent_utils import read_file
|
|
11
11
|
from bioguider.agents.prompt_utils import EVALUATION_INSTRUCTION
|
|
12
|
+
from bioguider.database.summarized_file_db import SummarizedFilesDb
|
|
12
13
|
from bioguider.utils.constants import DEFAULT_TOKEN_USAGE, ProjectMetadata
|
|
13
14
|
from .common_agent import CommonConversation
|
|
14
15
|
from ..utils.pyphen_utils import PyphenReadability
|
|
@@ -158,7 +159,8 @@ class EvaluationTask(ABC):
|
|
|
158
159
|
repo_path: str,
|
|
159
160
|
gitignore_path: str,
|
|
160
161
|
meta_data: ProjectMetadata | None = None,
|
|
161
|
-
step_callback: Callable | None = None
|
|
162
|
+
step_callback: Callable | None = None,
|
|
163
|
+
summarized_files_db: SummarizedFilesDb | None=None,
|
|
162
164
|
):
|
|
163
165
|
self.evaluation_name = ""
|
|
164
166
|
self.llm = llm
|
|
@@ -166,6 +168,8 @@ class EvaluationTask(ABC):
|
|
|
166
168
|
self.gitignore_path = gitignore_path
|
|
167
169
|
self.step_callback = step_callback
|
|
168
170
|
self.metadata = meta_data
|
|
171
|
+
self.summarized_files_db = summarized_files_db
|
|
172
|
+
|
|
169
173
|
def print_step(
|
|
170
174
|
self,
|
|
171
175
|
step_name: str | None = None,
|
|
@@ -180,11 +184,12 @@ class EvaluationTask(ABC):
|
|
|
180
184
|
token_usage=token_usage,
|
|
181
185
|
)
|
|
182
186
|
|
|
183
|
-
def evaluate(self
|
|
187
|
+
def evaluate(self) -> dict:
|
|
184
188
|
self._enter_evaluation()
|
|
185
|
-
|
|
189
|
+
files = self._collect_files()
|
|
190
|
+
evaluations, token_usage, files = self._evaluate(files)
|
|
186
191
|
self._leave_evaluation(token_usage)
|
|
187
|
-
return evaluations
|
|
192
|
+
return evaluations, files
|
|
188
193
|
|
|
189
194
|
def _enter_evaluation(self):
|
|
190
195
|
self.print_step(step_name=self.evaluation_name)
|
|
@@ -196,6 +201,10 @@ class EvaluationTask(ABC):
|
|
|
196
201
|
def _evaluate(self, files: list[str]) -> tuple[dict, dict]:
|
|
197
202
|
pass
|
|
198
203
|
|
|
204
|
+
@abstractmethod
|
|
205
|
+
def _collect_files(self) -> list[str]:
|
|
206
|
+
pass
|
|
207
|
+
|
|
199
208
|
|
|
200
209
|
EVALUATION_TUTORIAL_SYSTEM_PROMPT="""
|
|
201
210
|
You are an expert in software documentation and developer education.
|
|
@@ -262,9 +271,10 @@ class EvaluationTutorialTask(EvaluationTask):
|
|
|
262
271
|
repo_path: str,
|
|
263
272
|
gitignore_path: str,
|
|
264
273
|
meta_data: ProjectMetadata | None = None,
|
|
265
|
-
step_callback: Callable | None = None
|
|
274
|
+
step_callback: Callable | None = None,
|
|
275
|
+
summarized_files_db = None,
|
|
266
276
|
):
|
|
267
|
-
super().__init__(llm, repo_path, gitignore_path, meta_data, step_callback)
|
|
277
|
+
super().__init__(llm, repo_path, gitignore_path, meta_data, step_callback, summarized_files_db)
|
|
268
278
|
self.evaluation_name = "Tutorial Evaluation"
|
|
269
279
|
|
|
270
280
|
def _evaluate(self, files: list[str]) -> tuple[dict, dict]:
|
|
@@ -300,4 +310,7 @@ class EvaluationTutorialTask(EvaluationTask):
|
|
|
300
310
|
self.print_step(step_output=response)
|
|
301
311
|
evaluations[file] = response
|
|
302
312
|
return evaluations, token_usage
|
|
313
|
+
|
|
314
|
+
def _collect_files(self):
|
|
315
|
+
return []
|
|
303
316
|
|
|
@@ -34,6 +34,9 @@ Carefully review the **Goal**, **Repository File Structure**, and **Intermediate
|
|
|
34
34
|
```
|
|
35
35
|
Be precise and support your reasoning with evidence from the input.
|
|
36
36
|
|
|
37
|
+
### **Important Instructions**
|
|
38
|
+
{important_instructions}
|
|
39
|
+
|
|
37
40
|
### Notes
|
|
38
41
|
We are collecting information over multiple rounds, your thoughts and the output of this step will be persisted, so please **do not rush to provide a Final Answer**.
|
|
39
42
|
If you find the current information insufficient, share your reasoning or thoughts instead—we’ll continue with the next round accordingly.
|
|
@@ -58,6 +61,8 @@ class IdentificationObserveStep(PEOCommonStep):
|
|
|
58
61
|
|
|
59
62
|
def _prepare_system_prompt(self, state: IdentificationWorkflowState):
|
|
60
63
|
goal = state["goal"]
|
|
64
|
+
important_instructions = "N/A" \
|
|
65
|
+
if not "observe_instructions" in state else state["observe_instructions"]
|
|
61
66
|
final_answer_example = state["final_answer_example"]
|
|
62
67
|
intermediate_output = self._build_intermediate_steps(state)
|
|
63
68
|
prompt = ChatPromptTemplate.from_template(IDENTIFICATION_OBSERVATION_SYSTEM_PROMPT)
|
|
@@ -67,11 +72,12 @@ class IdentificationObserveStep(PEOCommonStep):
|
|
|
67
72
|
repo_structure=self.repo_structure,
|
|
68
73
|
intermediate_output=intermediate_output,
|
|
69
74
|
final_answer_example=final_answer_example,
|
|
75
|
+
important_instructions=important_instructions,
|
|
70
76
|
)
|
|
71
77
|
|
|
72
78
|
def _execute_directly(self, state: IdentificationWorkflowState):
|
|
73
79
|
system_prompt = self._prepare_system_prompt(state)
|
|
74
|
-
agent =
|
|
80
|
+
agent = CommonAgentTwoSteps(llm=self.llm)
|
|
75
81
|
res, _, token_usage, reasoning_process = agent.go(
|
|
76
82
|
system_prompt=system_prompt,
|
|
77
83
|
instruction_prompt="Now, let's begin.",
|
|
@@ -36,6 +36,9 @@ meaning that states and variables will persisted through multiple rounds of plan
|
|
|
36
36
|
developing your collection plan incrementally and reflect on the intermediate observations at each round, instead of coding up
|
|
37
37
|
everything in one go. Be sure to take only one or two actions in each step.
|
|
38
38
|
|
|
39
|
+
### **Important Instructions**
|
|
40
|
+
{important_instructions}
|
|
41
|
+
|
|
39
42
|
### **Output**
|
|
40
43
|
You plan should follow this format:
|
|
41
44
|
Step: tool name, should be one of {tool_names}
|
|
@@ -81,6 +84,7 @@ class IdentificationPlanStep(PEOCommonStep):
|
|
|
81
84
|
|
|
82
85
|
def _prepare_system_prompt(self, state: IdentificationWorkflowState) -> str:
|
|
83
86
|
goal = state["goal"]
|
|
87
|
+
important_instructions = "N/A" if not "plan_instructions" in state else state["plan_instructions"]
|
|
84
88
|
repo_structure = self.repo_structure
|
|
85
89
|
intermdediate_steps = self._build_intermediate_steps(state)
|
|
86
90
|
step_analysis, step_thoughts = self._build_intermediate_analysis_and_thoughts(state)
|
|
@@ -101,6 +105,7 @@ class IdentificationPlanStep(PEOCommonStep):
|
|
|
101
105
|
intermediate_analysis=step_analysis,
|
|
102
106
|
intermediate_thoughts=step_thoughts,
|
|
103
107
|
tool_names=tool_names,
|
|
108
|
+
important_instructions=important_instructions,
|
|
104
109
|
)
|
|
105
110
|
|
|
106
111
|
def _convert_to_plan_actions_text(self, actions: list[dict]) -> str:
|
|
@@ -113,7 +118,7 @@ class IdentificationPlanStep(PEOCommonStep):
|
|
|
113
118
|
|
|
114
119
|
def _execute_directly(self, state: IdentificationWorkflowState):
|
|
115
120
|
system_prompt = self._prepare_system_prompt(state)
|
|
116
|
-
agent =
|
|
121
|
+
agent = CommonAgentTwoSteps(llm=self.llm)
|
|
117
122
|
res, _, token_usage, reasoning_process = agent.go(
|
|
118
123
|
system_prompt=system_prompt,
|
|
119
124
|
instruction_prompt="Now, let's begin.",
|
|
@@ -64,14 +64,17 @@ class IdentificationTask(AgentTask):
|
|
|
64
64
|
self,
|
|
65
65
|
llm: BaseChatOpenAI,
|
|
66
66
|
step_callback: Callable | None=None,
|
|
67
|
+
summarized_files_db: SummarizedFilesDb | None = None,
|
|
68
|
+
provided_files: list[str] | None = None,
|
|
67
69
|
):
|
|
68
|
-
super().__init__(llm=llm, step_callback=step_callback)
|
|
70
|
+
super().__init__(llm=llm, step_callback=step_callback, summarized_files_db=summarized_files_db)
|
|
69
71
|
self.repo_path: str | None = None
|
|
70
72
|
self.gitignore_path: str | None = None
|
|
71
73
|
self.repo_structure: str | None = None
|
|
72
74
|
self.tools = []
|
|
73
75
|
self.custom_tools = []
|
|
74
76
|
self.steps: list[PEOCommonStep] = []
|
|
77
|
+
self.provided_files = provided_files
|
|
75
78
|
|
|
76
79
|
def _prepare_tools(self):
|
|
77
80
|
tool_rd = read_directory_tool(repo_path=self.repo_path)
|
|
@@ -79,7 +82,7 @@ class IdentificationTask(AgentTask):
|
|
|
79
82
|
llm=self.llm,
|
|
80
83
|
repo_path=self.repo_path,
|
|
81
84
|
output_callback=self.step_callback,
|
|
82
|
-
db=self.
|
|
85
|
+
db=self.summarized_files_db,
|
|
83
86
|
)
|
|
84
87
|
tool_rf = read_file_tool(repo_path=self.repo_path)
|
|
85
88
|
|
|
@@ -106,7 +109,9 @@ class IdentificationTask(AgentTask):
|
|
|
106
109
|
def _initialize(self):
|
|
107
110
|
if not os.path.exists(self.repo_path):
|
|
108
111
|
raise ValueError(f"Repository path {self.repo_path} does not exist.")
|
|
109
|
-
files =
|
|
112
|
+
files = self.provided_files
|
|
113
|
+
if files is None:
|
|
114
|
+
files = read_directory(self.repo_path, os.path.join(self.repo_path, ".gitignore"))
|
|
110
115
|
file_pairs = [(f, get_file_type(os.path.join(self.repo_path, f)).value) for f in files]
|
|
111
116
|
self.repo_structure = ""
|
|
112
117
|
for f, f_type in file_pairs:
|
|
@@ -188,7 +193,21 @@ class IdentificationTask(AgentTask):
|
|
|
188
193
|
meta_data = s["final_answer"] if "final_answer" in s else "unknown type"
|
|
189
194
|
return self._parse_meta_data(meta_data)
|
|
190
195
|
|
|
191
|
-
|
|
196
|
+
def identify_customize_goal(
|
|
197
|
+
self,
|
|
198
|
+
goal: str,
|
|
199
|
+
final_answer_example: str,
|
|
200
|
+
plan_instructions: str = "N/A",
|
|
201
|
+
observe_instructions: str = "N/A",
|
|
202
|
+
):
|
|
203
|
+
s = self._go_graph({
|
|
204
|
+
"goal": goal,
|
|
205
|
+
"final_answer_example": final_answer_example,
|
|
206
|
+
"plan_instructions": plan_instructions,
|
|
207
|
+
"observe_instructions": observe_instructions,
|
|
208
|
+
})
|
|
209
|
+
return s["final_answer"] if "final_answer" in s else None
|
|
210
|
+
|
|
192
211
|
def _parse_project_type(self, proj_type_obj: str) -> ProjectTypeEnum:
|
|
193
212
|
proj_type_obj = proj_type_obj.strip()
|
|
194
213
|
the_obj = try_parse_json_object(proj_type_obj)
|
|
@@ -10,6 +10,8 @@ class IdentificationWorkflowState(TypedDict):
|
|
|
10
10
|
|
|
11
11
|
plan_actions: Optional[str]
|
|
12
12
|
plan_reasoning: Optional[str]
|
|
13
|
+
plan_instructions: Optional[str]
|
|
14
|
+
observe_instructions: Optional[str]
|
|
13
15
|
intermediate_steps: Optional[list[str]]
|
|
14
16
|
final_answer: Optional[str]
|
|
15
17
|
final_answer_example: Optional[str]
|
bioguider/agents/prompt_utils.py
CHANGED
|
@@ -91,6 +91,7 @@ class CollectionGoalItemEnum(Enum):
|
|
|
91
91
|
Installation = "Installation"
|
|
92
92
|
License = "License"
|
|
93
93
|
Contributing = "Contributing"
|
|
94
|
+
SoftwarePackageContent = "SoftwarePackageContent"
|
|
94
95
|
|
|
95
96
|
|
|
96
97
|
|
|
@@ -147,12 +148,18 @@ If **any one** of these is present, the document should be classified as a Docke
|
|
|
147
148
|
* Examples: `example.py`, `main.py`, `demo.R`, `notebooks/get_started.ipynb`, etc.
|
|
148
149
|
* These should be runnable with minimal configuration.""",
|
|
149
150
|
|
|
150
|
-
"
|
|
151
|
+
"plan_important_instructions": """- Only include minimal code examples that demonstrate basic functionality.
|
|
151
152
|
If multiple example files are found, select only the simplest and most lightweight one that is sufficient to verify the repository works.
|
|
152
153
|
- Give priority to analyzing files whose names include **"install"** or **"Dockerfile"**, as these are most likely to be useful for generating our Dockerfile
|
|
153
154
|
- The total number of collected files should **not exceed 5**.
|
|
154
155
|
- Make sure to include **only one code example**, selecting the most minimal and representative one.
|
|
155
|
-
"""
|
|
156
|
+
""",
|
|
157
|
+
"observe_important_instructions": """- Only include minimal code examples that demonstrate basic functionality.
|
|
158
|
+
If multiple example files are found, select only the simplest and most lightweight one that is sufficient to verify the repository works.
|
|
159
|
+
- Give priority to analyzing files whose names include **"install"** or **"Dockerfile"**, as these are most likely to be useful for generating our Dockerfile
|
|
160
|
+
- The total number of collected files should **not exceed 5**.
|
|
161
|
+
- Make sure to include **only one code example**, selecting the most minimal and representative one.
|
|
162
|
+
""",
|
|
156
163
|
},
|
|
157
164
|
"Installation": {
|
|
158
165
|
"goal_item": "Installation Instructions",
|
|
@@ -163,11 +170,16 @@ If **any one** of these is present, the document should be classified as Install
|
|
|
163
170
|
- Configuration steps required to get the software running.
|
|
164
171
|
- Troubleshooting tips related to installation issues.
|
|
165
172
|
- You can include directory names if all files in the directory are relevant to the goal item.""",
|
|
166
|
-
"
|
|
173
|
+
"plan_important_instructions": """ - Give priority to analyzing README file that contain installation instructions and the files whose names include **"install"** or **"setup"**.
|
|
167
174
|
- If multiple files are found, select the most comprehensive one that covers the installation process.
|
|
168
175
|
- The total number of collected files should **not exceed 3**.
|
|
169
176
|
- Identify and select **no more than three** installation instruction files — choose the most comprehensive and representative ones.
|
|
170
|
-
"""
|
|
177
|
+
""",
|
|
178
|
+
"observe_important_instructions": """ - Give priority to analyzing README file that contain installation instructions and the files whose names include **"install"** or **"setup"**.
|
|
179
|
+
- If multiple files are found, select the most comprehensive one that covers the installation process.
|
|
180
|
+
- The total number of collected files should **not exceed 3**.
|
|
181
|
+
- Identify and select **no more than three** installation instruction files — choose the most comprehensive and representative ones.
|
|
182
|
+
""",
|
|
171
183
|
},
|
|
172
184
|
"License": {
|
|
173
185
|
"goal_item": "License Information",
|
|
@@ -187,6 +199,34 @@ If **any one** of these is present, the document should be classified as Contrib
|
|
|
187
199
|
- Any file that contains instructions for developers on how to contribute to the project, including coding standards, testing procedures, and submission processes.
|
|
188
200
|
- You can include directory names if all files in the directory are relevant to the goal item.""",
|
|
189
201
|
},
|
|
202
|
+
"SoftwarePackageContent": {
|
|
203
|
+
"goal_item": "Software Package Content",
|
|
204
|
+
"related_file_description": """A file qualifies as **Software Package Content** if it meets **at least one** of the following elements.
|
|
205
|
+
- A compiled binary file that may be qualified as a compiled standalone software, please carefully analyze a binary file and its file name to identify if it is a compiled standalone software
|
|
206
|
+
- A source code file, like a file whose extension is `.py`, `.R`, `.ipynb`, `.ts`, or `.js`.
|
|
207
|
+
- An example data which is used to demonstrate usage or for tutorial. Image file should not be considered as example data.
|
|
208
|
+
""",
|
|
209
|
+
"plan_important_instructions": """ - A comiled standalone software file is non-textual and appears to be in an executable format (e.g., `.exe`, `.dll`, `.so`, `.bin`, `.elf`).
|
|
210
|
+
- A comiled standalone software file **is not a script or compiled library**, that is, It is not a wrapper script (e.g., shell, Python, Python notebook or Rmd) nor a dynamic/shared library meant for linking.
|
|
211
|
+
- When identifying source code file, prioritize analyzing the file's **extension** and **file name** and try to avoid reading file, using check_file_related_tool or summarizing file content.
|
|
212
|
+
- When identifying example data, prioritize analyzing the file's **extension** (like .dat, .csv, .fastq, and so on) and **file name** (like example_data.txt, example.dat, and so on). If extension/name is ambiguous, use summarizing file content to decide.
|
|
213
|
+
- **Note**: You **only need to detect** whether at least **one** compiled standalone software file, **one** source code file and **one** example data file exist — no need to list all such files.
|
|
214
|
+
""",
|
|
215
|
+
"observe_important_instructions": """ - A comiled standalone software file is non-textual and appears to be in an executable format (e.g., `.exe`, `.dll`, `.so`, `.bin`, `.elf`).
|
|
216
|
+
- A comiled standalone software file **is not a script or compiled library**, that is, It is not a wrapper script (e.g., shell, Python, Python notebook or Rmd) nor a dynamic/shared library meant for linking.
|
|
217
|
+
- When identifying source code file, prioritize analyzing the file's **extension** and **file name** and try to avoid reading file, using check_file_related_tool or summarizing file content.
|
|
218
|
+
- When identifying example data, prioritize analyzing the file's **extension** (like .dat, .csv, .fastq, and so on) and **file name** (like example_data.txt, example.dat, and so on). If extension/name is ambiguous, use summarizing file content to decide.
|
|
219
|
+
- **Note**: You **only need to detect** whether at least **one** compiled standalone software file, **one** source code file and **one** example data file exist — no need to list all such files.
|
|
220
|
+
- **Final answer format**: If you believe **all relevant files** have been collected:
|
|
221
|
+
Your final answer **must exactly match** the following format:
|
|
222
|
+
**FinalAnswer:** {{"final_answer": [<N/A or a compiled filename>, <N/A or a source file name>, <N/A or a example data file name>]}}
|
|
223
|
+
For each category, return a single file name or `"N/A"` if none found. And the return array must exactly follow this order: [<A comiled standalone software file name>, <A source code file name>, <A example data file name>]
|
|
224
|
+
For example, **FinalAnswer:** {{"final_answer": ["N/A", "app.py", "example.csv"]}} indicates:
|
|
225
|
+
* No compiled standalone software found
|
|
226
|
+
* `app.py` found as source code
|
|
227
|
+
* `example.csv` found as example data
|
|
228
|
+
""",
|
|
229
|
+
},
|
|
190
230
|
}
|
|
191
231
|
|
|
192
232
|
|
|
@@ -11,6 +11,7 @@ from ..utils.file_utils import parse_repo_url
|
|
|
11
11
|
from ..database.summarized_file_db import SummarizedFilesDb
|
|
12
12
|
from ..agents.evaluation_readme_task import EvaluationREADMETask
|
|
13
13
|
from ..agents.evaluation_installation_task import EvaluationInstallationTask
|
|
14
|
+
from ..agents.evaluation_submission_requirements_task import EvaluationSubmissionRequirementsTask
|
|
14
15
|
from ..agents.collection_task import CollectionTask
|
|
15
16
|
|
|
16
17
|
class EvaluationManager:
|
|
@@ -65,69 +66,60 @@ class EvaluationManager:
|
|
|
65
66
|
gitignore_path=Path(self.rag.repo_dir, ".gitignore"),
|
|
66
67
|
meta_data=self.project_metadata,
|
|
67
68
|
step_callback=self.step_callback,
|
|
69
|
+
summarized_files_db=self.summary_file_db,
|
|
68
70
|
)
|
|
69
|
-
readme_files = self._find_readme_files()
|
|
70
|
-
results = task.evaluate(
|
|
71
|
+
# readme_files = self._find_readme_files()
|
|
72
|
+
results, readme_files = task.evaluate()
|
|
71
73
|
return results, readme_files
|
|
72
74
|
|
|
73
75
|
def evaluate_tutorial(self):
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
76
|
+
pass
|
|
77
|
+
# task = CollectionTask(
|
|
78
|
+
# llm=self.llm,
|
|
79
|
+
# step_callback=self.step_callback,
|
|
80
|
+
# )
|
|
81
|
+
# task.compile(
|
|
82
|
+
# repo_path=self.rag.repo_dir,
|
|
83
|
+
# gitignore_path=Path(self.rag.repo_dir, ".gitignore"),
|
|
84
|
+
# db=self.summary_file_db,
|
|
85
|
+
# goal_item=CollectionGoalItemEnum.Tutorial.name,
|
|
86
|
+
# )
|
|
87
|
+
# s = task.collect()
|
|
88
|
+
# if s is None or 'final_answer' not in s:
|
|
89
|
+
# return None
|
|
87
90
|
|
|
88
91
|
def evaluate_installation(self):
|
|
89
|
-
|
|
92
|
+
evaluation_task = EvaluationInstallationTask(
|
|
90
93
|
llm=self.llm,
|
|
91
|
-
step_callback=self.step_callback,
|
|
92
|
-
)
|
|
93
|
-
task.compile(
|
|
94
94
|
repo_path=self.rag.repo_dir,
|
|
95
95
|
gitignore_path=Path(self.rag.repo_dir, ".gitignore"),
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
meta_data=self.project_metadata,
|
|
97
|
+
step_callback=self.step_callback,
|
|
98
98
|
)
|
|
99
|
-
files =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
evaluation, files = evaluation_task.evaluate()
|
|
100
|
+
return evaluation, files
|
|
101
|
+
|
|
102
|
+
def evaluate_submission_requirements(
|
|
103
|
+
self,
|
|
104
|
+
readme_files_evaluation: dict | None = None,
|
|
105
|
+
installation_files: list[str] | None = None,
|
|
106
|
+
installation_evaluation: dict[str] | None = None,
|
|
107
|
+
):
|
|
108
|
+
evaluation_task = EvaluationSubmissionRequirementsTask(
|
|
103
109
|
llm=self.llm,
|
|
104
110
|
repo_path=self.rag.repo_dir,
|
|
105
111
|
gitignore_path=Path(self.rag.repo_dir, ".gitignore"),
|
|
106
112
|
meta_data=self.project_metadata,
|
|
107
113
|
step_callback=self.step_callback,
|
|
114
|
+
summarized_files_db=self.summary_file_db,
|
|
115
|
+
readme_files_evaluation=readme_files_evaluation,
|
|
116
|
+
installation_files=installation_files,
|
|
117
|
+
installation_evaluation=installation_evaluation,
|
|
108
118
|
)
|
|
109
|
-
evaluation = evaluation_task.evaluate(
|
|
119
|
+
evaluation, files = evaluation_task.evaluate()
|
|
120
|
+
|
|
110
121
|
return evaluation, files
|
|
111
122
|
|
|
112
|
-
|
|
113
|
-
"""
|
|
114
|
-
Search for a README file in the repository directory.
|
|
115
|
-
"""
|
|
116
|
-
possible_readme_files = [
|
|
117
|
-
"readme.md",
|
|
118
|
-
"readme.rst",
|
|
119
|
-
"readme.txt",
|
|
120
|
-
"readme",
|
|
121
|
-
]
|
|
122
|
-
repo_path = self.rag.repo_dir
|
|
123
|
-
gitignore_path = Path(repo_path, ".gitignore")
|
|
124
|
-
gitignore_checker = GitignoreChecker(
|
|
125
|
-
directory=repo_path, gitignore_path=gitignore_path
|
|
126
|
-
)
|
|
127
|
-
found_readme_files = gitignore_checker.check_files_and_folders(
|
|
128
|
-
check_file_cb=lambda root_dir, relative_path: Path(relative_path).name.lower() in possible_readme_files,
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
return found_readme_files
|
|
123
|
+
|
|
132
124
|
|
|
133
125
|
|
bioguider/utils/constants.py
CHANGED
|
@@ -1,49 +1,50 @@
|
|
|
1
1
|
bioguider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
bioguider/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
bioguider/agents/agent_task.py,sha256=
|
|
4
|
-
bioguider/agents/agent_tools.py,sha256=
|
|
5
|
-
bioguider/agents/agent_utils.py,sha256=
|
|
3
|
+
bioguider/agents/agent_task.py,sha256=B_QGkoA96GdrYSX29TQ_tct_y8z4zS4l5Cn0-eph88k,2863
|
|
4
|
+
bioguider/agents/agent_tools.py,sha256=r21wHV6a-Ic2T0dk4YzA-_d7PodHPM3GzRxJqv-llSw,7286
|
|
5
|
+
bioguider/agents/agent_utils.py,sha256=FFFhZvL_THvZ2Y7QwFmi3jsUd1i7PYi9tPJNMTVUsgY,14702
|
|
6
6
|
bioguider/agents/collection_execute_step.py,sha256=Ev4BLjjmBdsc52M1zrq7QK8g7fsffDkSxu-jN2rvedw,5614
|
|
7
|
-
bioguider/agents/collection_observe_step.py,sha256=
|
|
8
|
-
bioguider/agents/collection_plan_step.py,sha256=
|
|
9
|
-
bioguider/agents/collection_task.py,sha256=
|
|
10
|
-
bioguider/agents/collection_task_utils.py,sha256=
|
|
7
|
+
bioguider/agents/collection_observe_step.py,sha256=N_P5NadFa0usO0M9cXXJvKJoZofwcDW0cPSfnwvPEO4,4786
|
|
8
|
+
bioguider/agents/collection_plan_step.py,sha256=Nn0f8AOkEDCDtnhaqE7yCQoi7PVpsHmiUcsIqC0T0dQ,5956
|
|
9
|
+
bioguider/agents/collection_task.py,sha256=ZLUxDgh8OkY5INMfC283RdxEYCZJTksoLDNEMfKg-3s,7865
|
|
10
|
+
bioguider/agents/collection_task_utils.py,sha256=CmOh3HZEocuLj5VZCkLbD6P8O5tzyuyFa8Ykd-1GPGE,5356
|
|
11
11
|
bioguider/agents/common_agent.py,sha256=eGs8m8bjO0dmW6lDIen7DQNdWdHD7j8Udf3XhL1k6vI,5242
|
|
12
12
|
bioguider/agents/common_agent_2step.py,sha256=Vton0RKtmMyEgIIFhnBk4CFU_hynX0LvwREcZ9kvMxQ,7918
|
|
13
13
|
bioguider/agents/common_step.py,sha256=GdOCbmj1pwh4etg-futVFYVDQuoUG89DnIrw-B6QbzM,2594
|
|
14
14
|
bioguider/agents/dockergeneration_execute_step.py,sha256=F92jDlkc6KjAvTkX7q1FsCYP8J15SCaNgmwh3YPqfDo,6500
|
|
15
15
|
bioguider/agents/dockergeneration_observe_step.py,sha256=93PO_Y4YyUShVTKRt0nErcjb-xYTcwcZCj7TgniS9t4,6098
|
|
16
16
|
bioguider/agents/dockergeneration_plan_step.py,sha256=SB8tQM9PkIKsD2o1DFD7bedcxz6r6hSy8n_EVK60Fz0,7235
|
|
17
|
-
bioguider/agents/dockergeneration_task.py,sha256=
|
|
17
|
+
bioguider/agents/dockergeneration_task.py,sha256=mYmorLKnJ-Jku3Qq_Y_kcSTsbYIo3RiVdD0puxqXY5Q,6221
|
|
18
18
|
bioguider/agents/dockergeneration_task_utils.py,sha256=v7emqrJlVW-A5ZdLmPSdiaMSKCR8uzy9UYzx_1cgzyo,9041
|
|
19
|
-
bioguider/agents/evaluation_installation_task.py,sha256=
|
|
20
|
-
bioguider/agents/evaluation_readme_task.py,sha256=
|
|
21
|
-
bioguider/agents/
|
|
19
|
+
bioguider/agents/evaluation_installation_task.py,sha256=9AVE5PJB69aoDX0WMkye0UkYstSU2CsjzVB3eaPrLQo,11128
|
|
20
|
+
bioguider/agents/evaluation_readme_task.py,sha256=_v7ESqMurOg4UXCGqc1zmaVscBx3QbznrUdAKQH9Zws,22597
|
|
21
|
+
bioguider/agents/evaluation_submission_requirements_task.py,sha256=rFCI6bTl64kRiUkEwbh6Ef1LV-YqrgJhGkHaaqE_Pp8,6647
|
|
22
|
+
bioguider/agents/evaluation_task.py,sha256=4VZ7l8oqcUsgJ2YY6s6mkcJu25DgA1qLXv2kVUm2SgI,12654
|
|
22
23
|
bioguider/agents/identification_execute_step.py,sha256=w3IjL8f2WiHCyiLjVSoySnIAXpi1-hK1DLKCnXbAN2Y,5587
|
|
23
|
-
bioguider/agents/identification_observe_step.py,sha256=
|
|
24
|
-
bioguider/agents/identification_plan_step.py,sha256=
|
|
25
|
-
bioguider/agents/identification_task.py,sha256=
|
|
26
|
-
bioguider/agents/identification_task_utils.py,sha256=
|
|
24
|
+
bioguider/agents/identification_observe_step.py,sha256=U-iWDR1AZIUpthEswtMbMkPK4YAbAv2SrvBJAqdKyZo,3988
|
|
25
|
+
bioguider/agents/identification_plan_step.py,sha256=owsTK1NZIuiZL7QPVknJyp9TBRK-mhnuf2RwK4YzaxU,5442
|
|
26
|
+
bioguider/agents/identification_task.py,sha256=hVhgExCv1OPMgOYOGRRJyR3-uiG-VR-OgrvWT6vLn9M,10031
|
|
27
|
+
bioguider/agents/identification_task_utils.py,sha256=nWRK3kCyiglw7576idiDGXEzUBBInkz_w9OsK6OJv2E,599
|
|
27
28
|
bioguider/agents/peo_common_step.py,sha256=iw2c1h7X11WJzSE2tSRg0UAoXH0QOlQDxW9CCzSVMOY,2677
|
|
28
|
-
bioguider/agents/prompt_utils.py,sha256=
|
|
29
|
+
bioguider/agents/prompt_utils.py,sha256=M-KUqGPhtOyFlDN1yNNZdOxTOPFjACF5VhBFW7gXgSc,17151
|
|
29
30
|
bioguider/agents/python_ast_repl_tool.py,sha256=o7-4P1h8jS8ikhGSA4CI_OWQ2a0Eg5tEdmuAp_qrO-0,2519
|
|
30
31
|
bioguider/agents/rag_collection_task.py,sha256=r_jPAMjQcC7dIydKxX77UuMqjJ3MiVKswNZ-yNw7yx8,5199
|
|
31
32
|
bioguider/conversation.py,sha256=DIvk_d7pz_guuORByK1eaaF09FAK-8shcNTrbSUHz9Y,1779
|
|
32
33
|
bioguider/database/summarized_file_db.py,sha256=tDSi2iCvm2-lrx0rBJo0C11gYl9FswsDZTG2-Yhu5cE,4646
|
|
33
|
-
bioguider/managers/evaluation_manager.py,sha256=
|
|
34
|
+
bioguider/managers/evaluation_manager.py,sha256=O8mxrAGllDIkcQVsrRrqxH0eyJHwtoSauWrPe_F7qqU,4778
|
|
34
35
|
bioguider/rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
36
|
bioguider/rag/config.py,sha256=5g4IqTzgyfZfax9Af9CTkXShgItPOt4_9TEMSekCPik,4602
|
|
36
37
|
bioguider/rag/data_pipeline.py,sha256=bkJ2IUCgPx_OL2uZtPd6cIBor2VFZEIfGd5kVlmiPjw,27292
|
|
37
38
|
bioguider/rag/embedder.py,sha256=jofR8hOj3Aj2IyBQ9y6FeAc84tgq5agbIfCGyFxYpJ8,650
|
|
38
39
|
bioguider/rag/rag.py,sha256=JFPwrJlKDSyd3U3Gce_NSxI5343eNUbqPG9Fs5Pfoq0,4696
|
|
39
40
|
bioguider/settings.py,sha256=BD_iz9aYarxmWUl0XaKl4-D4oTXMhFzljsXLNn2phis,3143
|
|
40
|
-
bioguider/utils/constants.py,sha256=
|
|
41
|
+
bioguider/utils/constants.py,sha256=4PbzF-s49M0nNtGsLjxQ9-APaJqNAjCQrE0wunSvPqw,982
|
|
41
42
|
bioguider/utils/default.gitignore,sha256=XjPdyO2KV8z8iyuqluaNR_70tBQftMpyKL8HboVNyeI,1605
|
|
42
43
|
bioguider/utils/file_utils.py,sha256=9VfAHsz1UkFPtzAmvWZvPl1TMaKIYNjNlLgsfB8tNjg,3683
|
|
43
44
|
bioguider/utils/gitignore_checker.py,sha256=pOYUwsS9D5014LxcZb0cj3s2CAYaD2uF_pYJpaNKcho,6532
|
|
44
45
|
bioguider/utils/pyphen_utils.py,sha256=cdZc3qphkvMDeL5NiZ8Xou13M_uVNP7ifJ-FwxO-0BE,2680
|
|
45
46
|
bioguider/utils/utils.py,sha256=YP3HXgU_rvYDWkEcTzWGiYZw-mlfVrqGhUGSc0_4Pms,900
|
|
46
|
-
bioguider-0.2.
|
|
47
|
-
bioguider-0.2.
|
|
48
|
-
bioguider-0.2.
|
|
49
|
-
bioguider-0.2.
|
|
47
|
+
bioguider-0.2.13.dist-info/LICENSE,sha256=qzkvZcKwwA5DuSuhXMOm2LcO6BdEr4V7jwFZVL2-jL4,1065
|
|
48
|
+
bioguider-0.2.13.dist-info/METADATA,sha256=HpVwAdlrLxjQ5JVIm-prHV33vHyxPHi3IID4x8l-l_c,1868
|
|
49
|
+
bioguider-0.2.13.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
50
|
+
bioguider-0.2.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|