mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-04 03:13:20 +00:00
fix: move to gpt 5.2 codex and run formatter (#967)
This commit is contained in:
parent
ad57a72719
commit
bbf89ed2d7
8 changed files with 1289 additions and 1131 deletions
|
|
@ -9,7 +9,7 @@ import contextlib
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import Any
|
||||||
|
|
||||||
from deepagents.backends.protocol import (
|
from deepagents.backends.protocol import (
|
||||||
ExecuteResponse,
|
ExecuteResponse,
|
||||||
|
|
@ -19,7 +19,6 @@ from deepagents.backends.protocol import (
|
||||||
WriteResult,
|
WriteResult,
|
||||||
)
|
)
|
||||||
from deepagents.backends.sandbox import BaseSandbox
|
from deepagents.backends.sandbox import BaseSandbox
|
||||||
|
|
||||||
from langsmith.sandbox import Sandbox, SandboxClient, SandboxTemplate
|
from langsmith.sandbox import Sandbox, SandboxClient, SandboxTemplate
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -148,9 +147,7 @@ class LangSmithBackend(BaseSandbox):
|
||||||
responses: list[FileDownloadResponse] = []
|
responses: list[FileDownloadResponse] = []
|
||||||
for path in paths:
|
for path in paths:
|
||||||
content = self._sandbox.read(path)
|
content = self._sandbox.read(path)
|
||||||
responses.append(
|
responses.append(FileDownloadResponse(path=path, content=content, error=None))
|
||||||
FileDownloadResponse(path=path, content=content, error=None)
|
|
||||||
)
|
|
||||||
return responses
|
return responses
|
||||||
|
|
||||||
def upload_files(self, files: list[tuple[str, bytes]]) -> list[FileUploadResponse]:
|
def upload_files(self, files: list[tuple[str, bytes]]) -> list[FileUploadResponse]:
|
||||||
|
|
@ -209,10 +206,7 @@ class LangSmithProvider(SandboxProvider):
|
||||||
template_name=resolved_template_name, timeout=timeout
|
template_name=resolved_template_name, timeout=timeout
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = (
|
msg = f"Failed to create sandbox from template '{resolved_template_name}': {e}"
|
||||||
f"Failed to create sandbox from template "
|
|
||||||
f"'{resolved_template_name}': {e}"
|
|
||||||
)
|
|
||||||
raise RuntimeError(msg) from e
|
raise RuntimeError(msg) from e
|
||||||
|
|
||||||
# Verify sandbox is ready by polling
|
# Verify sandbox is ready by polling
|
||||||
|
|
|
||||||
|
|
@ -181,16 +181,12 @@ I've {action} pull request to address this issue:
|
||||||
|
|
||||||
logger.info("Changes detected, preparing PR for thread %s", thread_id)
|
logger.info("Changes detected, preparing PR for thread %s", thread_id)
|
||||||
|
|
||||||
current_branch = await asyncio.to_thread(
|
current_branch = await asyncio.to_thread(git_current_branch, sandbox_backend, repo_dir)
|
||||||
git_current_branch, sandbox_backend, repo_dir
|
|
||||||
)
|
|
||||||
|
|
||||||
target_branch = f"open-swe/{thread_id}"
|
target_branch = f"open-swe/{thread_id}"
|
||||||
|
|
||||||
if current_branch != target_branch:
|
if current_branch != target_branch:
|
||||||
await asyncio.to_thread(
|
await asyncio.to_thread(git_checkout_branch, sandbox_backend, repo_dir, target_branch)
|
||||||
git_checkout_branch, sandbox_backend, repo_dir, target_branch
|
|
||||||
)
|
|
||||||
|
|
||||||
await asyncio.to_thread(
|
await asyncio.to_thread(
|
||||||
git_config_user,
|
git_config_user,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
# Suppress deprecation warnings from langchain_core (e.g., Pydantic V1 on Python 3.14+)
|
# Suppress deprecation warnings from langchain_core (e.g., Pydantic V1 on Python 3.14+)
|
||||||
# ruff: noqa: E402
|
# ruff: noqa: E402
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
@ -24,11 +23,10 @@ warnings.filterwarnings("ignore", message=".*Pydantic V1.*", category=UserWarnin
|
||||||
# Now safe to import agent (which imports LangChain modules)
|
# Now safe to import agent (which imports LangChain modules)
|
||||||
from deepagents import create_deep_agent
|
from deepagents import create_deep_agent
|
||||||
from deepagents.backends.protocol import SandboxBackendProtocol
|
from deepagents.backends.protocol import SandboxBackendProtocol
|
||||||
|
from langchain_openai import ChatOpenAI
|
||||||
# Local import for encryption
|
|
||||||
from langchain_anthropic import ChatAnthropic
|
|
||||||
|
|
||||||
from .encryption import decrypt_token
|
from .encryption import decrypt_token
|
||||||
|
from .integrations.langsmith import _create_langsmith_sandbox
|
||||||
from .middleware import (
|
from .middleware import (
|
||||||
ToolErrorMiddleware,
|
ToolErrorMiddleware,
|
||||||
check_message_queue_before_model,
|
check_message_queue_before_model,
|
||||||
|
|
@ -37,8 +35,6 @@ from .middleware import (
|
||||||
)
|
)
|
||||||
from .prompt import construct_system_prompt
|
from .prompt import construct_system_prompt
|
||||||
from .tools import commit_and_open_pr, fetch_url, http_request
|
from .tools import commit_and_open_pr, fetch_url, http_request
|
||||||
from .integrations.langsmith import _create_langsmith_sandbox
|
|
||||||
|
|
||||||
|
|
||||||
client = get_client()
|
client = get_client()
|
||||||
|
|
||||||
|
|
@ -46,12 +42,12 @@ SANDBOX_CREATING = "__creating__"
|
||||||
SANDBOX_CREATION_TIMEOUT = 180
|
SANDBOX_CREATION_TIMEOUT = 180
|
||||||
SANDBOX_POLL_INTERVAL = 1.0
|
SANDBOX_POLL_INTERVAL = 1.0
|
||||||
|
|
||||||
from .utils.sandbox_state import SANDBOX_BACKENDS, get_sandbox_id_from_metadata
|
|
||||||
from .utils.github import (
|
from .utils.github import (
|
||||||
git_has_uncommitted_changes,
|
git_has_uncommitted_changes,
|
||||||
is_valid_git_repo,
|
is_valid_git_repo,
|
||||||
remove_directory,
|
remove_directory,
|
||||||
)
|
)
|
||||||
|
from .utils.sandbox_state import SANDBOX_BACKENDS, get_sandbox_id_from_metadata
|
||||||
|
|
||||||
|
|
||||||
async def _clone_or_pull_repo_in_sandbox( # noqa: PLR0915
|
async def _clone_or_pull_repo_in_sandbox( # noqa: PLR0915
|
||||||
|
|
@ -87,9 +83,7 @@ async def _clone_or_pull_repo_in_sandbox( # noqa: PLR0915
|
||||||
is_git_repo = await loop.run_in_executor(None, is_valid_git_repo, sandbox_backend, repo_dir)
|
is_git_repo = await loop.run_in_executor(None, is_valid_git_repo, sandbox_backend, repo_dir)
|
||||||
|
|
||||||
if not is_git_repo:
|
if not is_git_repo:
|
||||||
logger.warning(
|
logger.warning("Repo directory missing or not a valid git repo at %s, removing", repo_dir)
|
||||||
"Repo directory missing or not a valid git repo at %s, removing", repo_dir
|
|
||||||
)
|
|
||||||
try:
|
try:
|
||||||
removed = await loop.run_in_executor(None, remove_directory, sandbox_backend, repo_dir)
|
removed = await loop.run_in_executor(None, remove_directory, sandbox_backend, repo_dir)
|
||||||
if not removed:
|
if not removed:
|
||||||
|
|
@ -336,7 +330,7 @@ async def get_agent(config: RunnableConfig) -> Pregel: # noqa: PLR0915
|
||||||
|
|
||||||
logger.info("Returning agent with sandbox for thread %s", thread_id)
|
logger.info("Returning agent with sandbox for thread %s", thread_id)
|
||||||
return create_deep_agent(
|
return create_deep_agent(
|
||||||
model=ChatAnthropic(model="claude-opus-4-6", max_tokens=20_000),
|
model=ChatOpenAI(model="gpt-5.2-codex", temperature=0, max_tokens=20_000),
|
||||||
system_prompt=construct_system_prompt(
|
system_prompt=construct_system_prompt(
|
||||||
repo_dir,
|
repo_dir,
|
||||||
linear_project_id=linear_project_id,
|
linear_project_id=linear_project_id,
|
||||||
|
|
|
||||||
|
|
@ -181,9 +181,7 @@ def commit_and_open_pr(
|
||||||
"pr_url": None,
|
"pr_url": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
base_branch = asyncio.run(
|
base_branch = asyncio.run(get_github_default_branch(repo_owner, repo_name, github_token))
|
||||||
get_github_default_branch(repo_owner, repo_name, github_token)
|
|
||||||
)
|
|
||||||
pr_url, _pr_number, pr_existing = asyncio.run(
|
pr_url, _pr_number, pr_existing = asyncio.run(
|
||||||
create_github_pr(
|
create_github_pr(
|
||||||
repo_owner=repo_owner,
|
repo_owner=repo_owner,
|
||||||
|
|
|
||||||
|
|
@ -37,24 +37,18 @@ def remove_directory(sandbox_backend: SandboxBackendProtocol, repo_dir: str) ->
|
||||||
return result.exit_code == 0
|
return result.exit_code == 0
|
||||||
|
|
||||||
|
|
||||||
def git_has_uncommitted_changes(
|
def git_has_uncommitted_changes(sandbox_backend: SandboxBackendProtocol, repo_dir: str) -> bool:
|
||||||
sandbox_backend: SandboxBackendProtocol, repo_dir: str
|
|
||||||
) -> bool:
|
|
||||||
"""Check whether the repo has uncommitted changes."""
|
"""Check whether the repo has uncommitted changes."""
|
||||||
result = _run_git(sandbox_backend, repo_dir, "git status --porcelain")
|
result = _run_git(sandbox_backend, repo_dir, "git status --porcelain")
|
||||||
return result.exit_code == 0 and bool(result.output.strip())
|
return result.exit_code == 0 and bool(result.output.strip())
|
||||||
|
|
||||||
|
|
||||||
def git_fetch_origin(
|
def git_fetch_origin(sandbox_backend: SandboxBackendProtocol, repo_dir: str) -> ExecuteResponse:
|
||||||
sandbox_backend: SandboxBackendProtocol, repo_dir: str
|
|
||||||
) -> ExecuteResponse:
|
|
||||||
"""Fetch latest from origin (best-effort)."""
|
"""Fetch latest from origin (best-effort)."""
|
||||||
return _run_git(sandbox_backend, repo_dir, "git fetch origin 2>/dev/null || true")
|
return _run_git(sandbox_backend, repo_dir, "git fetch origin 2>/dev/null || true")
|
||||||
|
|
||||||
|
|
||||||
def git_has_unpushed_commits(
|
def git_has_unpushed_commits(sandbox_backend: SandboxBackendProtocol, repo_dir: str) -> bool:
|
||||||
sandbox_backend: SandboxBackendProtocol, repo_dir: str
|
|
||||||
) -> bool:
|
|
||||||
"""Check whether there are commits not pushed to upstream."""
|
"""Check whether there are commits not pushed to upstream."""
|
||||||
git_log_cmd = (
|
git_log_cmd = (
|
||||||
"git log --oneline @{upstream}..HEAD 2>/dev/null "
|
"git log --oneline @{upstream}..HEAD 2>/dev/null "
|
||||||
|
|
@ -75,9 +69,7 @@ def git_checkout_branch(
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Checkout branch, creating it if needed."""
|
"""Checkout branch, creating it if needed."""
|
||||||
safe_branch = shlex.quote(branch)
|
safe_branch = shlex.quote(branch)
|
||||||
checkout_result = _run_git(
|
checkout_result = _run_git(sandbox_backend, repo_dir, f"git checkout -b {safe_branch}")
|
||||||
sandbox_backend, repo_dir, f"git checkout -b {safe_branch}"
|
|
||||||
)
|
|
||||||
if checkout_result.exit_code == 0:
|
if checkout_result.exit_code == 0:
|
||||||
return True
|
return True
|
||||||
fallback = _run_git(sandbox_backend, repo_dir, f"git checkout {safe_branch}")
|
fallback = _run_git(sandbox_backend, repo_dir, f"git checkout {safe_branch}")
|
||||||
|
|
@ -97,9 +89,7 @@ def git_config_user(
|
||||||
_run_git(sandbox_backend, repo_dir, f"git config user.email {safe_email}")
|
_run_git(sandbox_backend, repo_dir, f"git config user.email {safe_email}")
|
||||||
|
|
||||||
|
|
||||||
def git_add_all(
|
def git_add_all(sandbox_backend: SandboxBackendProtocol, repo_dir: str) -> ExecuteResponse:
|
||||||
sandbox_backend: SandboxBackendProtocol, repo_dir: str
|
|
||||||
) -> ExecuteResponse:
|
|
||||||
"""Stage all changes."""
|
"""Stage all changes."""
|
||||||
return _run_git(sandbox_backend, repo_dir, "git add -A")
|
return _run_git(sandbox_backend, repo_dir, "git add -A")
|
||||||
|
|
||||||
|
|
@ -112,9 +102,7 @@ def git_commit(
|
||||||
return _run_git(sandbox_backend, repo_dir, f"git commit -m {safe_message}")
|
return _run_git(sandbox_backend, repo_dir, f"git commit -m {safe_message}")
|
||||||
|
|
||||||
|
|
||||||
def git_get_remote_url(
|
def git_get_remote_url(sandbox_backend: SandboxBackendProtocol, repo_dir: str) -> str | None:
|
||||||
sandbox_backend: SandboxBackendProtocol, repo_dir: str
|
|
||||||
) -> str | None:
|
|
||||||
"""Get the origin remote URL."""
|
"""Get the origin remote URL."""
|
||||||
result = _run_git(sandbox_backend, repo_dir, "git remote get-url origin")
|
result = _run_git(sandbox_backend, repo_dir, "git remote get-url origin")
|
||||||
if result.exit_code != 0:
|
if result.exit_code != 0:
|
||||||
|
|
|
||||||
|
|
@ -76,9 +76,11 @@ LINEAR_TEAM_TO_REPO: dict[str, dict[str, Any] | dict[str, str]] = {
|
||||||
"open-swe-v3-test": {"owner": "aran-yogesh", "name": "nimedge"},
|
"open-swe-v3-test": {"owner": "aran-yogesh", "name": "nimedge"},
|
||||||
"open-swe-dev-test": {"owner": "aran-yogesh", "name": "TalkBack"},
|
"open-swe-dev-test": {"owner": "aran-yogesh", "name": "TalkBack"},
|
||||||
},
|
},
|
||||||
"default": {"owner": "aran-yogesh", "name": "TalkBack"} # Fallback for issues without project
|
"default": {
|
||||||
|
"owner": "aran-yogesh",
|
||||||
|
"name": "TalkBack",
|
||||||
|
}, # Fallback for issues without project
|
||||||
},
|
},
|
||||||
|
|
||||||
"LangChain OSS": {
|
"LangChain OSS": {
|
||||||
"projects": {
|
"projects": {
|
||||||
"deepagents": {"owner": "langchain-ai", "name": "deepagents"},
|
"deepagents": {"owner": "langchain-ai", "name": "deepagents"},
|
||||||
|
|
@ -91,9 +93,7 @@ LINEAR_TEAM_TO_REPO: dict[str, dict[str, Any] | dict[str, str]] = {
|
||||||
},
|
},
|
||||||
"default": {"owner": "langchain-ai", "name": "ai-sdr"},
|
"default": {"owner": "langchain-ai", "name": "ai-sdr"},
|
||||||
},
|
},
|
||||||
"Docs": {
|
"Docs": {"default": {"owner": "langchain-ai", "name": "docs"}},
|
||||||
"default": {"owner": "langchain-ai", "name": "docs"}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ dependencies = [
|
||||||
"langgraph-cli[inmem]>=0.4.12",
|
"langgraph-cli[inmem]>=0.4.12",
|
||||||
# LangSmith SDK for sandbox management
|
# LangSmith SDK for sandbox management
|
||||||
"langsmith>=0.7.1",
|
"langsmith>=0.7.1",
|
||||||
|
"langchain-openai==1.1.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
|
|
|
||||||
2345
apps/agent/uv.lock
generated
2345
apps/agent/uv.lock
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue