{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "6c88d5c2-fa1b-4a26-8381-72c2d9946b54",
"metadata": {},
"outputs": [],
"source": [
"import subprocess\n",
"import os\n",
"\n",
"result = subprocess.run('bash -c \"source /etc/network_turbo && env | grep proxy\"', shell=True, capture_output=True, text=True)\n",
"output = result.stdout\n",
"for line in output.splitlines():\n",
" if '=' in line:\n",
" var, value = line.split('=', 1)\n",
" os.environ[var] = value"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "4f8ba095-d1d2-4422-92d3-0ab12f3d3570",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/root/miniconda3/lib/python3.12/site-packages/pydantic/_internal/_config.py:345: UserWarning: Valid config keys have changed in V2:\n",
"* 'fields' has been removed\n",
" warnings.warn(message, UserWarning)\n",
"[nltk_data] Downloading package punkt_tab to\n",
"[nltk_data] /root/miniconda3/lib/python3.12/site-\n",
"[nltk_data] packages/llama_index/core/_static/nltk_cache...\n",
"[nltk_data] Package punkt_tab is already up-to-date!\n",
"/root/miniconda3/lib/python3.12/site-packages/pydantic/_internal/_fields.py:192: UserWarning: Field name \"name\" in \"FeedbackResponse\" shadows an attribute in parent \"StructuredOutput\"\n",
" warnings.warn(\n"
]
}
],
"source": [
"import os\n",
"import json\n",
"import random\n",
"from typing import Optional, Dict, Any, List, Callable, Union\n",
"from pydantic import BaseModel, Field, model_validator\n",
"from textwrap import dedent\n",
"from litellm.types.llms.openai import ChatCompletionUserMessage\n",
"\n",
"from moatless.benchmark.utils import get_moatless_instance\n",
"from moatless.completion.model import StructuredOutput, Completion\n",
"from moatless.completion.completion import CompletionModel, CompletionResponse\n",
"\n",
"from moatless.repository.repository import Repository\n",
"from moatless.benchmark.swebench import create_repository\n",
"from moatless.index import CodeIndex\n",
"from moatless.file_context import FileContext\n",
"from moatless.selector import BestFirstSelector, Selector, SoftmaxSelector, LLMSelector\n",
"from moatless.selector.feedback_selector import FeedbackSelector\n",
"from moatless.feedback import FeedbackGenerator\n",
"from moatless.feedback.feedback_agent import FeedbackAgent\n",
"from moatless.value_function.base import ValueFunction\n",
"\n",
"from moatless.actions.action import Action\n",
"from moatless.actions import FindClass, FindFunction, FindCodeSnippet, SemanticSearch, ViewCode, Finish, Reject, RunTests, StringReplace, CreateFile, InsertLine\n",
"from moatless.agent.code_agent import CodingAgent, create_edit_code_actions\n",
"from moatless.agent.code_prompts import *\n",
"from moatless.agent.agent import ActionAgent\n",
"from moatless.search_tree import SearchTree\n",
"from moatless.completion.completion import (\n",
" LLMResponseFormat,\n",
" CompletionModel,\n",
")\n",
"from moatless.schema import MessageHistoryType\n",
"from moatless.message_history import MessageHistoryGenerator\n",
"from moatless.agent.settings import AgentSettings\n",
"from moatless.node import Node, ActionStep\n",
"from moatless.expander import Expander\n",
"from moatless.value_function.model import Reward\n",
"from moatless.exceptions import RuntimeError, RejectError"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "d02040e5-3bce-4959-bf8c-497f0ec77cb1",
"metadata": {},
"outputs": [],
"source": [
"class SilinSearchTree(BaseModel):\n",
" root: Node = Field(..., description=\"The root node of the search tree.\")\n",
" selector: Union[\n",
" BestFirstSelector, SoftmaxSelector, LLMSelector, FeedbackSelector\n",
" ] = Field(..., description=\"Selector for node selection.\")\n",
" agent: ActionAgent = Field(..., description=\"Agent for generating actions.\")\n",
" actions: List[Action] = Field(\n",
" default_factory=list,\n",
" description=\"Actions that can be used by the agent in the search tree.\",\n",
" )\n",
" repository: Optional[Repository] = Field(\n",
" None, description=\"Repository for the search tree.\"\n",
" )\n",
" expander: Optional[Expander] = Field(\n",
" None, description=\"Expander for expanding nodes.\"\n",
" )\n",
" value_function: Optional[ValueFunction] = Field(\n",
" None, description=\"Value function for reward calculation.\"\n",
" )\n",
" feedback_generator: Optional[FeedbackGenerator] = Field(\n",
" None, description=\"Feedback generator.\"\n",
" )\n",
" \n",
" persist_path: Optional[str] = Field(\n",
" None, description=\"Path to persist the search tree.\"\n",
" )\n",
" unique_id: int = Field(default=0, description=\"Unique ID counter for nodes.\")\n",
"\n",
" max_expansions: int = Field(\n",
" 1, description=\"The maximum number of expansions of one state.\"\n",
" )\n",
" max_iterations: int = Field(\n",
" 10, description=\"The maximum number of iterations to run the tree search.\"\n",
" )\n",
" min_finished_nodes: Optional[int] = Field(\n",
" None,\n",
" description=\"The minimum number of finished nodes to consider before finishing\",\n",
" )\n",
" max_finished_nodes: Optional[int] = Field(\n",
" None,\n",
" description=\"The maximum number of finished nodes to consider before finishing\",\n",
" )\n",
" max_depth: Optional[int] = Field(\n",
" None, description=\"The maximum depth for one trajectory in simulations.\"\n",
" )\n",
" \n",
" \n",
" class Config:\n",
" arbitrary_types_allowed = True\n",
" \n",
"\n",
" @classmethod\n",
" def create(\n",
" cls,\n",
" message: Optional[str] = None,\n",
" root: Optional[Node] = None,\n",
" file_context: Optional[FileContext] = None,\n",
" repository: Repository | None = None,\n",
" expander: Expander | None = None,\n",
" selector: Optional[Selector] = None,\n",
" agent: Optional[ActionAgent] = None,\n",
" value_function: Optional[ValueFunction] = None,\n",
" feedback_generator: Optional[FeedbackGenerator] = None,\n",
" persist_path: Optional[str] = None,\n",
" max_expansions: int = 1,\n",
" max_iterations: int = 10,\n",
" max_depth: int = 10,\n",
" ) -> \"SilinSearchTree\":\n",
" if not root and not message:\n",
" raise ValueError(\"Either a root node or a message must be provided.\")\n",
"\n",
" if not file_context:\n",
" file_context = FileContext(repo=repository)\n",
"\n",
" if not root:\n",
" root = Node(\n",
" node_id=0,\n",
" max_expansions=max_expansions,\n",
" user_message=message,\n",
" file_context=file_context,\n",
" )\n",
"\n",
" selector = selector or BestFirstSelector()\n",
" expander = Expander(max_expansions=max_expansions)\n",
"\n",
" return cls(\n",
" root=root,\n",
" selector=selector,\n",
" expander=expander,\n",
" agent=agent,\n",
" value_function=value_function,\n",
" feedback_generator=feedback_generator,\n",
" persist_path=persist_path,\n",
" max_expansions=max_expansions,\n",
" max_iterations=max_iterations,\n",
" max_depth=max_depth,\n",
" )\n",
" \n",
"\n",
" def run_search(self) -> Node | None:\n",
" \"\"\"Run the MCTS algorithm for a specified number of iterations.\"\"\"\n",
" # if len(self.root.get_all_nodes()) > 1:\n",
" # self.log(\n",
" # logger.info,\n",
" # f\"Restarting search tree with {len(self.root.get_all_nodes())} nodes\",\n",
" # )\n",
"\n",
" while not self.is_finished():\n",
" node = self._select(self.root)\n",
"\n",
" if node:\n",
" new_node = self._expand(node)\n",
" self._simulate(new_node)\n",
" self._backpropagate(new_node)\n",
" # self.maybe_persist()\n",
" # 如果生成的节点的action是Finish就跳出来,只完成一次trajectory\n",
" if new_node.is_terminal():\n",
" break\n",
" else:\n",
" print(\"Search complete: no more nodes to expand.\")\n",
" break\n",
"\n",
" if not len(self.get_finished_nodes()):\n",
" print(\n",
" f\"Search completed with no finished nodes. {len(self.root.get_all_nodes())} nodes created.\",\n",
" )\n",
" else:\n",
" print(\n",
" f\"Search completed with {len(self.get_finished_nodes())} finished nodes. {len(self.root.get_all_nodes())} nodes created.\",\n",
" )\n",
"\n",
" return self.get_all_trajectory()\n",
" \n",
"\n",
" def _select(self, node: Node) -> Optional[Node]:\n",
" \"\"\"Select a node for expansion using the UCT algorithm.\"\"\"\n",
" expandable_nodes = node.get_expandable_descendants()\n",
"\n",
" if not expandable_nodes:\n",
" print(\"No expandable nodes found.\")\n",
" return None\n",
"\n",
" # if expandable_nodes and self.finish_before_reexpanding:\n",
" # # Sort by node_id to get the most recently created node\n",
" # latest_node = max(expandable_nodes, key=lambda n: n.node_id)\n",
"\n",
" # # Check if any node in the tree has reached a finished state\n",
" # all_nodes = node.get_all_nodes()\n",
" # has_finished_node = any(n.is_finished() for n in all_nodes)\n",
"\n",
" # # Check if any node has exceeded the depth limit\n",
" # max_depth_exceeded = (\n",
" # any(\n",
" # n.get_depth() >= self.finish_before_reexpanding_depth\n",
" # for n in all_nodes\n",
" # )\n",
" # if self.finish_before_reexpanding_depth is not None\n",
" # else False\n",
" # )\n",
"\n",
" # # Continue linear expansion only if no finished nodes exist and depth never exceeded\n",
" # if not has_finished_node and not max_depth_exceeded:\n",
" # return latest_node\n",
" # else:\n",
" # self.log(\n",
" # logger.info,\n",
" # f\"Breaking linear path: {'finished state exists' if has_finished_node else 'depth limit exceeded'}\",\n",
" # )\n",
"\n",
" # If we have a finished node or exceeded depth, use normal selection\n",
" return self.selector.select(expandable_nodes)\n",
" \n",
"\n",
" def _expand(self, node: Node, force_expansion: bool = False) -> Node:\n",
" \"\"\"Expand the node and return a child node.\"\"\"\n",
"\n",
" # Check if any action step was not executed, if so return the node\n",
" if node.action_steps and node.has_unexecuted_actions():\n",
" print(\n",
" f\"Returning Node{node.node_id} with unexecuted actions\"\n",
" )\n",
" return node\n",
"\n",
" child_node = self.expander.expand(node, self, force_expansion)\n",
"\n",
" if not node.action_steps and node.assistant_message:\n",
" child_node.user_message = \"You're an autonomous AI agent that must respond with one of the provided functions\"\n",
"\n",
" # Only add feedback if this is the second expansion from this node\n",
" if self.feedback_generator and len(node.children) >= 2:\n",
" child_node.feedback_data = self.feedback_generator.generate_feedback(\n",
" child_node,\n",
" self.agent.actions,\n",
" )\n",
"\n",
" print(\n",
" f\"Expanded Node{node.node_id} to new Node{child_node.node_id}\"\n",
" )\n",
" return child_node\n",
" \n",
"\n",
" def _simulate(self, node: Node):\n",
" \"\"\"Simulate a playout by executing the action and evaluating the result.\"\"\"\n",
"\n",
" if node.observation:\n",
" print(f\"Node{node.node_id}: Action already executed. Skipping.\")\n",
" else:\n",
" self.agent.run(node)\n",
"\n",
" if self.value_function and not node.is_duplicate and node.observation:\n",
" try:\n",
" node.reward, completion_response = self.value_function.get_reward(\n",
" node=node\n",
" )\n",
" node.completions[\"value_function\"] = completion_response\n",
" print(\n",
" f\"Node{node.node_id}: The value function returned a reward of {node.reward.value}.\",\n",
" )\n",
" except RejectError as e:\n",
" print(\n",
" f\"Node{node.node_id}: Value function rejected: {e.message}\",\n",
" )\n",
" node.reward = None\n",
" except RuntimeError as e:\n",
" print(\n",
" f\"Node{node.node_id}: Value function runtime error: {e.message}\",\n",
" )\n",
" raise # Re-raise to abort the entire search\n",
"\n",
" \n",
" def _backpropagate(self, node: Node):\n",
" \"\"\"Backpropagate the reward up the tree.\"\"\"\n",
" \n",
" if not node.reward:\n",
" print(\n",
" f\"Node{node.node_id} has no evaluation. Skipping backpropagation.\",\n",
" )\n",
" return\n",
" \n",
" reward = node.reward.value\n",
" while node is not None:\n",
" node.visits += 1\n",
" if not node.value:\n",
" node.value = reward\n",
" else:\n",
" node.value += reward\n",
" node = node.parent\n",
"\n",
" \n",
" def get_finished_nodes(self) -> List[Node]:\n",
" \"\"\"Get all finished nodes in the search tree by uniqe parent node.\"\"\"\n",
" parent_ids = set()\n",
" finished_nodes = []\n",
" for node in self.root.get_all_nodes():\n",
" # TODO: Pick finished node with highest/avg/lowest reward?\n",
" if node.is_finished() and node.parent.node_id not in parent_ids:\n",
" parent_ids.add(node.parent.node_id)\n",
" finished_nodes.append(node)\n",
"\n",
" return finished_nodes\n",
"\n",
" \n",
" def is_finished(self):\n",
" # Check whether the last nods's terminal flag is True or not (whether the last action is Finish)\n",
" \n",
" \n",
" # Check max iterations\n",
" if len(self.root.get_all_nodes()) >= self.max_iterations:\n",
" print(\n",
" f\"Search finished: Reached max iterations {self.max_iterations}\"\n",
" )\n",
" return True\n",
"\n",
" finished_nodes = self.get_finished_nodes()\n",
" unique_finished_parents = set()\n",
" for node in finished_nodes:\n",
" unique_finished_parents.add(node.parent.node_id)\n",
"\n",
" # Check if there are no more expandable nodes\n",
" expandable_nodes = self.root.get_expandable_descendants()\n",
" if not expandable_nodes:\n",
" print(\"Search finished: No more expandable nodes\")\n",
" return True\n",
"\n",
" return False\n",
"\n",
" \n",
" def get_leaf_nodes(self) -> List[Node]:\n",
" \"\"\"Get all leaf nodes in the search tree.\"\"\"\n",
" return [node for node in self.root.get_all_nodes() if node.is_leaf()]\n",
"\n",
" \n",
" def _generate_unique_id(self) -> int:\n",
" self.unique_id += 1\n",
" return self.unique_id\n",
"\n",
" \n",
" def get_best_trajectory(self) -> Node | None:\n",
" pass\n",
"\n",
" \n",
" def get_all_trajectory(self) -> Node | None:\n",
" \"\"\"\n",
" Get all finished trajectory to return\n",
" \"\"\"\n",
" nodes = self.get_finished_nodes()\n",
" if not nodes:\n",
" nodes = self.get_leaf_nodes()\n",
" print(\n",
" f\"get_best_trajectory() No finished nodes found. Will select from {len(nodes)} leaf nodes.\",\n",
" )\n",
"\n",
" if len(nodes) == 1:\n",
" return nodes[0]\n",
"\n",
" print(\n",
" \"No discriminator provided. Returning all the finished node.\",\n",
" )\n",
" return nodes\n",
"\n",
" # if self.discriminator is None:\n",
" # self.log(\n",
" # logger.info,\n",
" # \"No discriminator provided. Returning the first finished node.\",\n",
" # )\n",
" # return nodes[-1]\n",
"\n",
" # return self.discriminator.select(nodes)\n",
"\n",
" \n",
" def display_value(self, node):\n",
" # 自底向上打印node的value值\n",
" while node:\n",
" print(f'The value of Node {node.node_id} is {node.value}')\n",
" node = node.parent\n",
"\n",
" \n",
" def display_uct(self, node):\n",
" # 自底向上打印node的uct值\n",
" while node:\n",
" value = self.selector.uct_score(node)\n",
" print(f'The uct score list of Node {node.node_id} is {value}')\n",
" node = node.parent\n",
" \n",
" \n",
" def persist(self, **kwargs):\n",
" \"\"\"\n",
" Persist the entire SearchTree to a file.\n",
"\n",
" Args:\n",
" file_path (str): The path to the file where the tree will be saved.\n",
" \"\"\"\n",
" tree_data = self.model_dump(**kwargs)\n",
" os.makedirs(os.path.dirname(self.persist_path), exist_ok=True)\n",
" \n",
" with open(self.persist_path, \"w\") as f:\n",
" try:\n",
" json.dump(tree_data, f, indent=2)\n",
" except Exception as e:\n",
" print(\n",
" f\"Error saving search tree to {self.persist_path}: {tree_data}\"\n",
" )\n",
" raise e\n",
"\n",
" \n",
" def model_dump(self, **kwargs) -> Dict[str, Any]:\n",
" \"\"\"\n",
" Generate a dictionary representation of the SearchTree.\n",
"\n",
" Returns:\n",
" Dict[str, Any]: A dictionary representation of the search tree.\n",
" \"\"\"\n",
" data = {\n",
" field: getattr(self, field)\n",
" for field in self.model_fields\n",
" if field\n",
" not in [\n",
" \"root\",\n",
" \"selector\",\n",
" \"repository\",\n",
" \"agent\",\n",
" \"value_function\",\n",
" \"feedback_generator\",\n",
" # \"discriminator\",\n",
" \"persist_path\",\n",
" # \"event_handlers\",\n",
" ]\n",
" }\n",
"\n",
" data.pop(\"persist_path\", None)\n",
"\n",
" data[\"selector\"] = self.selector.model_dump(**kwargs)\n",
" data[\"expander\"] = self.expander.model_dump(**kwargs)\n",
" data[\"agent\"] = self.agent.model_dump(**kwargs)\n",
" # data[\"agent_settings\"] = (\n",
" # self.agent_settings.model_dump(**kwargs) if self.agent_settings else None\n",
" # )\n",
" data[\"repository\"] = (\n",
" self.repository.model_dump(**kwargs) if self.repository else None\n",
" )\n",
"\n",
" if self.value_function:\n",
" data[\"value_function\"] = self.value_function.model_dump(**kwargs)\n",
" # if self.feedback_generator:\n",
" # data[\"feedback_generator\"] = self.feedback_generator.model_dump(**kwargs)\n",
" # if self.discriminator:\n",
" # data[\"discriminator\"] = self.discriminator.model_dump(**kwargs)\n",
" # data = {}\n",
" data[\"root\"] = self.root.model_dump(**kwargs)\n",
"\n",
" return data"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "4bd421ae-f11c-4bde-86ac-ccaf0af5b65a",
"metadata": {},
"outputs": [],
"source": [
"def get_trajectory(path):\n",
" try:\n",
" with open(path, \"r\", encoding=\"utf-8\") as file:\n",
" data = json.load(file) # 解析 JSON 文件内容为 Python 对象\n",
" # print(\"JSON 文件内容:\")\n",
" # print(json.dumps(data, indent=4, ensure_ascii=False)) # 格式化输出\n",
" return data\n",
" except FileNotFoundError:\n",
" print(f\"错误:文件 {file_path} 未找到。\")\n",
" except json.JSONDecodeError:\n",
" print(f\"错误:文件 {file_path} 不是有效的 JSON 格式。\")\n",
" except Exception as e:\n",
" print(f\"发生错误:{e}\")"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "919a341c-9ab3-4ea8-8fb2-bc630f9f049e",
"metadata": {},
"outputs": [],
"source": [
"# completion_model = CompletionModel(model=\"deepseek/deepseek-chat\", temperature=0.7)\n",
"instance_id = \"pytest-dev__pytest-6202\"\n",
"completion_model = CompletionModel(model=\"openai/moonshot-v1-32k\", model_base_url=os.getenv(\"CUSTOM_LLM_API_BASE\"), model_api_key=os.getenv(\"CUSTOM_LLM_API_KEY\"), temperature=0.7)\n",
"instance = get_moatless_instance(instance_id=instance_id) # 获得的instance是本地下载下来有点删改属性的swe-bench\n",
"repository = create_repository(instance)\n",
"code_index = CodeIndex.from_index_name(\n",
" instance[\"instance_id\"], file_repo=repository\n",
")\n",
"file_context = FileContext(repo=repository)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "a36893fd-1c3f-48e4-a9bd-ccc9582a32c4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Problem Statement:\n",
"'.[' replaced with '[' in the headline shown of the test report\n",
"```\n",
"bug.py F [100%]\n",
"\n",
"=================================== FAILURES ===================================\n",
"_________________________________ test_boo[.[] _________________________________\n",
"\n",
"a = '..['\n",
"\n",
" @pytest.mark.parametrize(\"a\",[\"..[\"])\n",
" def test_boo(a):\n",
"> assert 0\n",
"E assert 0\n",
"\n",
"bug.py:6: AssertionError\n",
"============================== 1 failed in 0.06s ===============================\n",
"```\n",
"\n",
"The `\"test_boo[..[]\"` replaced with `\"test_boo[.[]\"` in the headline shown with long report output.\n",
"\n",
"**The same problem also causing the vscode-python test discovery error.**\n",
"\n",
"## What causing the problem\n",
"\n",
"I trace back the source code.\n",
"\n",
"[https://github.com/pytest-dev/pytest/blob/92d6a0500b9f528a9adcd6bbcda46ebf9b6baf03/src/_pytest/reports.py#L129-L149](https://github.com/pytest-dev/pytest/blob/92d6a0500b9f528a9adcd6bbcda46ebf9b6baf03/src/_pytest/reports.py#L129-L149)\n",
"\n",
"The headline comes from line 148.\n",
"\n",
"[https://github.com/pytest-dev/pytest/blob/92d6a0500b9f528a9adcd6bbcda46ebf9b6baf03/src/_pytest/nodes.py#L432-L441](https://github.com/pytest-dev/pytest/blob/92d6a0500b9f528a9adcd6bbcda46ebf9b6baf03/src/_pytest/nodes.py#L432-L441)\n",
"\n",
"`location` comes from line 437 `location = self.reportinfo()`\n",
"\n",
"[https://github.com/pytest-dev/pytest/blob/92d6a0500b9f528a9adcd6bbcda46ebf9b6baf03/src/_pytest/python.py#L294-L308](https://github.com/pytest-dev/pytest/blob/92d6a0500b9f528a9adcd6bbcda46ebf9b6baf03/src/_pytest/python.py#L294-L308)\n",
"\n",
"The headline comes from line 306 `modpath = self.getmodpath() `\n",
"\n",
"[https://github.com/pytest-dev/pytest/blob/92d6a0500b9f528a9adcd6bbcda46ebf9b6baf03/src/_pytest/python.py#L274-L292](https://github.com/pytest-dev/pytest/blob/92d6a0500b9f528a9adcd6bbcda46ebf9b6baf03/src/_pytest/python.py#L274-L292)\n",
"\n",
"This line of code `return s.replace(\".[\", \"[\")` causes the problem. We should replace it with `return s`. After changing this, run `tox -e linting,py37`, pass all the tests and resolve this issue. But I can't find this line of code for what purpose.\n",
"\n",
"----------------------------------------------------------------------------------------------------\n",
"Golden Patch:\n",
"diff --git a/src/_pytest/python.py b/src/_pytest/python.py\n",
"--- a/src/_pytest/python.py\n",
"+++ b/src/_pytest/python.py\n",
"@@ -285,8 +285,7 @@ def getmodpath(self, stopatmodule=True, includemodule=False):\n",
" break\n",
" parts.append(name)\n",
" parts.reverse()\n",
"- s = \".\".join(parts)\n",
"- return s.replace(\".[\", \"[\")\n",
"+ return \".\".join(parts)\n",
" \n",
" def reportinfo(self):\n",
" # XXX caching?\n",
"\n"
]
}
],
"source": [
"print('Problem Statement:\\n{}'.format(instance['problem_statement']))\n",
"print('-'*100)\n",
"print('Golden Patch:\\n{}'.format(instance['golden_patch']))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "51a5b053-a7cf-443d-ad0c-694596001b19",
"metadata": {},
"outputs": [],
"source": [
"from datetime import datetime\n",
"current_date = datetime.now().strftime(\"%Y-%m-%d\")\n",
"instance_path = f'/root/autodl-tmp/moatless-tree-search-main/tmp/trajectory/{instance_id}/'\n",
"persist_path = f'/root/autodl-tmp/moatless-tree-search-main/tmp/trajectory/{instance_id}/{current_date}_trajectory.json'"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "879bda56-0dc2-4e06-b765-40e70ed2aeb7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"model='openai/moonshot-v1-32k' temperature=0.7 max_tokens=2000 timeout=120.0 model_base_url='https://api.siliconflow.cn/v1' model_api_key='sk-smgaaslaksmyvscpyyebpyjvbwbajmrbukynqglorzfqvost' response_format=None stop_words=None metadata=None thoughts_in_action=False\n",
"model='openai/moonshot-v1-32k' temperature=0.7 max_tokens=2000 timeout=120.0 model_base_url='https://api.siliconflow.cn/v1' model_api_key='sk-smgaaslaksmyvscpyyebpyjvbwbajmrbukynqglorzfqvost' response_format=<LLMResponseFormat.TOOLS: 'tool_call'> stop_words=None metadata=None thoughts_in_action=False\n"
]
}
],
"source": [
"print(completion_model)\n",
"completion_model.response_format = LLMResponseFormat.TOOLS\n",
"print(completion_model)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "78cf4491-26cf-4b3c-a3ab-d8dd72570453",
"metadata": {},
"outputs": [],
"source": [
"value_function = ValueFunction(completion_model=completion_model)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "82cd6592-fda5-4f0b-b117-0ce304fbda89",
"metadata": {},
"outputs": [],
"source": [
"actions = [\n",
" FindClass(completion_model=completion_model, code_index=code_index, repository=repository),\n",
" FindFunction(completion_model=completion_model, code_index=code_index, repository=repository),\n",
" FindCodeSnippet(completion_model=completion_model, code_index=code_index, repository=repository),\n",
" SemanticSearch(completion_model=completion_model, code_index=code_index, repository=repository),\n",
" ViewCode(completion_model=completion_model, repository=repository),\n",
" StringReplace(repository=repository, code_index=code_index),\n",
" InsertLine(repository=repository),\n",
" CreateFile(repository=repository, code_index=code_index),\n",
" RunTests(repository=repository, code_index=code_index),\n",
" Finish(),\n",
" # Reject()\n",
"]\n",
"\n",
"system_prompt = AGENT_ROLE\n",
"if completion_model.response_format == LLMResponseFormat.REACT:\n",
" system_prompt += REACT_CORE_OPERATION_RULES\n",
"elif completion_model.response_format == LLMResponseFormat.TOOLS:\n",
" system_prompt += REACT_GUIDELINES\n",
"workflow_prompt = generate_workflow_prompt(actions, False)\n",
"system_prompt += workflow_prompt + generate_guideline_prompt(False) + ADDITIONAL_NOTES\n",
"# print(system_prompt)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "205af05b-6597-4f8b-aded-7168118016a0",
"metadata": {},
"outputs": [],
"source": [
"agent = CodingAgent(system_prompt=system_prompt, actions=actions, completion=completion_model)\n",
"# # 我认为应该是下面这种初始化,用的是内部的prompt而不是手动system_prompt,但是测试的时候是用了上面的初始化以及SIMPLE_CODE_PROMPT\n",
"# agent = CodingAgent.create(repository=repository, completion_model=completion_model)\n",
"# agent.actions = actions # if not, 它内部的action没有code index,也没有repository"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d0da41c0-3694-4a9a-ab8c-154dc9d7f117",
"metadata": {},
"outputs": [],
"source": [
"feedback_generator = FeedbackAgent(\n",
" completion_model=agent.completion, instance_dir=instance_path\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "03bfb01e-9acc-48b0-84e8-b91bc9027aff",
"metadata": {},
"outputs": [],
"source": [
"search_tree = SilinSearchTree.create(\n",
" message=instance[\"problem_statement\"],\n",
" agent=agent,\n",
" file_context=file_context,\n",
" value_function=value_function,\n",
" feedback_generator=feedback_generator,\n",
" max_iterations=100,\n",
" max_expansions=3,\n",
" max_depth=25,\n",
" persist_path=persist_path,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "908cb906-fc2b-499a-b23c-05cf4a12b547",
"metadata": {},
"source": [
"## First Rollout"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "92fd8cb7-4f9c-4704-b20f-837064539e39",
"metadata": {},
"outputs": [],
"source": [
"node = search_tree._select(search_tree.root)\n",
"node"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "baa21a43-79a0-4f4a-9a80-a56adf333548",
"metadata": {},
"outputs": [],
"source": [
"new_node = search_tree._expand(node)\n",
"new_node"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ffb2fe6e-243b-4ced-a074-bc9597fb1f7e",
"metadata": {},
"outputs": [],
"source": [
"search_tree._simulate(new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "950ccdfe-d0f6-4aba-af55-ba37ca4e87e1",
"metadata": {},
"outputs": [],
"source": [
"agent.message_generator.generate(new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e1259a0a-235f-4241-97b9-304755f840d2",
"metadata": {},
"outputs": [],
"source": [
"search_tree._backpropagate(new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7862ee51-8e02-4cd3-8475-d52ddd52e855",
"metadata": {},
"outputs": [],
"source": [
"search_tree.display_uct(new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1eb92c30-ab3a-4b8c-9b47-5c7590903442",
"metadata": {},
"outputs": [],
"source": [
"# search_tree.persist()"
]
},
{
"cell_type": "markdown",
"id": "cd5f3383-fbfd-437b-a7e2-129116657d03",
"metadata": {},
"source": [
"## Second Rollout"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "00167deb-ea9c-4519-a035-0ee4696a9451",
"metadata": {},
"outputs": [],
"source": [
"search_tree.is_finished()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8b3511ce-c4f7-439d-a02e-80ef3697da07",
"metadata": {},
"outputs": [],
"source": [
"second_node = search_tree._select(search_tree.root)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "814f9863-37ff-4fbe-9453-d18448383216",
"metadata": {},
"outputs": [],
"source": [
"second_new_node = search_tree._expand(second_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b5154001-efd4-4e0a-8291-724beb7713ab",
"metadata": {},
"outputs": [],
"source": [
"search_tree._simulate(second_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e65cbe03-1a62-4e37-93c5-483d8b3e7bc5",
"metadata": {},
"outputs": [],
"source": [
"search_tree._backpropagate(second_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5d9ef5c4-4f1f-4385-b98c-24490bbdfda7",
"metadata": {},
"outputs": [],
"source": [
"agent.message_generator.generate(second_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3c6bfab7-2491-49b4-8a5d-1114331cd725",
"metadata": {},
"outputs": [],
"source": [
"search_tree.display_uct(second_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1e4510e8-677b-49b6-b53f-c5320f097053",
"metadata": {},
"outputs": [],
"source": [
"print(second_new_node.action.old_str)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8d1d271e-73c0-4846-b28a-f9b3038ab472",
"metadata": {},
"outputs": [],
"source": [
"print(second_new_node.action.new_str)"
]
},
{
"cell_type": "markdown",
"id": "3c504454-3d22-49a2-b649-f924c33b3211",
"metadata": {},
"source": [
"## Third Rollout"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3f6f3eac-30ab-4a4c-bd13-9936209302b6",
"metadata": {},
"outputs": [],
"source": [
"search_tree.is_finished()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "680d8947-98bd-4564-9425-b5665d00b343",
"metadata": {},
"outputs": [],
"source": [
"third_node = search_tree._select(search_tree.root)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "520b5944-6433-4ee2-a73f-4d2ea3f31fd3",
"metadata": {},
"outputs": [],
"source": [
"third_new_node = search_tree._expand(third_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0413c5f8-9ce1-432c-bd7a-a351097fd686",
"metadata": {},
"outputs": [],
"source": [
"search_tree._simulate(third_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "daae91ca-fb51-41dc-ac0e-d812c26d66fa",
"metadata": {},
"outputs": [],
"source": [
"search_tree._backpropagate(third_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "67e7f145-543c-4e31-bfab-879a16604aa7",
"metadata": {},
"outputs": [],
"source": [
"print(third_new_node.observation.properties['diff'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4fa0fc8a-dccd-44d6-bec2-e353fc38caf7",
"metadata": {},
"outputs": [],
"source": [
"# search_tree.persist()"
]
},
{
"cell_type": "markdown",
"id": "0c244ee7-30be-44b9-9755-7f6f26ef77b8",
"metadata": {},
"source": [
"## Forth Rollout"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b7a7068e-1752-491c-9a62-199ebb5c6855",
"metadata": {},
"outputs": [],
"source": [
"search_tree.is_finished()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "441258ba-314c-4416-9a47-4bda186055b8",
"metadata": {},
"outputs": [],
"source": [
"forth_node = search_tree._select(search_tree.root)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4045f47c-2aef-47f5-83e3-3f44f814d2bd",
"metadata": {},
"outputs": [],
"source": [
"forth_new_node = search_tree._expand(forth_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e858b62b-a400-46bf-954d-41d6d56bd343",
"metadata": {},
"outputs": [],
"source": [
"search_tree._simulate(forth_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "57bdd4e6-164a-426b-be48-92b444ab885d",
"metadata": {},
"outputs": [],
"source": [
"agent.message_generator.generate(forth_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0c107c10-1769-418d-89f1-40b8b12b791f",
"metadata": {},
"outputs": [],
"source": [
"search_tree._backpropagate(forth_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2000943a-f7cb-46db-bc63-2ab8e2fa9be7",
"metadata": {},
"outputs": [],
"source": [
"print(forth_new_node.action.old_str)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3b23caec-c186-4ac8-8d9d-cca0d33de59a",
"metadata": {},
"outputs": [],
"source": [
"print(forth_new_node.action.new_str)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f0f9d961-90fb-46ff-af67-f0ac9945b262",
"metadata": {},
"outputs": [],
"source": [
"print(forth_new_node.observation.properties['diff'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6f4b85b7-7154-4973-8c28-528c5045c7aa",
"metadata": {},
"outputs": [],
"source": [
"search_tree.persist()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8780dbe6-7814-4e1f-9782-d86fa743083f",
"metadata": {},
"outputs": [],
"source": [
"# get_trajectory(search_tree.persist_path)"
]
},
{
"cell_type": "markdown",
"id": "d64d4932-ba10-4a8f-b834-9c05f9a5eedf",
"metadata": {},
"source": [
"## Fifth Rollout"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a18649ec-a6ed-4fa5-aa3a-1e1a5eaa3aa6",
"metadata": {},
"outputs": [],
"source": [
"search_tree.is_finished()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5465b9e9-20f0-4d63-9672-31294104d528",
"metadata": {},
"outputs": [],
"source": [
"fifth_node = search_tree._select(search_tree.root)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb6f5b84-8700-40e6-b2dd-53b02ba269b7",
"metadata": {},
"outputs": [],
"source": [
"fifth_new_node = search_tree._expand(fifth_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9421090a-ab91-4f2a-a100-ecaeab089184",
"metadata": {},
"outputs": [],
"source": [
"search_tree._simulate(fifth_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4a205776-d1ad-48bc-8bfe-ebd7f9ca541d",
"metadata": {},
"outputs": [],
"source": [
"search_tree._backpropagate(fifth_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4e4858cc-045f-49e1-8f22-4215b50833a0",
"metadata": {},
"outputs": [],
"source": [
"search_tree.display_uct(fifth_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4ad186e6-19fc-443e-b11f-cd02772018a6",
"metadata": {},
"outputs": [],
"source": [
"print(fifth_new_node.observation.properties['diff'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a3b5af5a-ef1b-42c9-8c18-ddec4017750f",
"metadata": {},
"outputs": [],
"source": [
"search_tree.persist()"
]
},
{
"cell_type": "markdown",
"id": "a01f7492-59c1-4a7f-93a3-05cab6b2e5b6",
"metadata": {},
"source": [
"## Sixth Rollout"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "327e90a8-bcce-459b-a3ae-eed7f7c30862",
"metadata": {},
"outputs": [],
"source": [
"search_tree.is_finished()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a222bc50-64ab-4f1f-8b10-3d030db01f9a",
"metadata": {},
"outputs": [],
"source": [
"sixth_node = search_tree._select(search_tree.root)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "36dfca20-376d-43f2-993b-d3ad26c36b31",
"metadata": {},
"outputs": [],
"source": [
"sixth_node.node_id"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3377f9a9-5bb9-479a-91a8-69944b3261db",
"metadata": {},
"outputs": [],
"source": [
"sixth_new_node = search_tree._expand(sixth_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8e9efa66-defa-44f3-86fb-5f0b44ef0815",
"metadata": {},
"outputs": [],
"source": [
"search_tree._simulate(sixth_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4a2e0097-c623-4131-9b6d-6dd9dfcc0c37",
"metadata": {},
"outputs": [],
"source": [
"search_tree._backpropagate(sixth_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6a842443-035c-4a2a-a067-7311940e318b",
"metadata": {},
"outputs": [],
"source": [
"# search_tree.persist()"
]
},
{
"cell_type": "markdown",
"id": "96fb672e-b16d-4698-8aaf-5abdd7b83f12",
"metadata": {},
"source": [
"## Seventh Rollout"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ee2973ed-0760-4e85-bd25-1fa846973950",
"metadata": {},
"outputs": [],
"source": [
"search_tree.is_finished()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "36470128-d90a-4877-a825-9ab9101d9cb1",
"metadata": {},
"outputs": [],
"source": [
"seventh_node = search_tree._select(search_tree.root)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "80e6980b-3d68-471a-915f-a1783a788381",
"metadata": {},
"outputs": [],
"source": [
"seventh_new_node = search_tree._expand(seventh_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "44ea8297-4ee1-40eb-8fb9-3d9f42ef39d2",
"metadata": {},
"outputs": [],
"source": [
"search_tree._simulate(seventh_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fc909b2b-7b61-44e8-ac99-affa3769dd18",
"metadata": {},
"outputs": [],
"source": [
"print(seventh_new_node.observation.properties['diff'])"
]
},
{
"cell_type": "markdown",
"id": "aec8cb4d-b4e5-43fe-bf88-5e37ef08943f",
"metadata": {},
"source": [
"## eighth rollout"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f0b6eaa4-f4e3-4a40-9521-6b385b173371",
"metadata": {},
"outputs": [],
"source": [
"search_tree.is_finished()\n",
"eighth_node = search_tree._select(search_tree.root)\n",
"eighth_new_node = search_tree._expand(eighth_node)\n",
"search_tree._simulate(eighth_new_node)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9ef70f7b-39dc-4e85-9a9e-6b4d8841be82",
"metadata": {},
"outputs": [],
"source": [
"search_tree._backpropagate(eighth_new_node)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Workflows from the Neura Market marketplace related to this DeepSeek resource