diff --git a/.github/workflows/openhands-resolver.yml b/.github/workflows/openhands-resolver.yml index b3fc07c..c32a7a0 100644 --- a/.github/workflows/openhands-resolver.yml +++ b/.github/workflows/openhands-resolver.yml @@ -18,6 +18,10 @@ on: required: true PAT_USERNAME: required: true + RUNTIME: + required: false + ALLHANDS_API_KEY: + required: false issues: types: [labeled] @@ -113,6 +117,8 @@ jobs: LLM_MODEL: ${{ secrets.LLM_MODEL }} LLM_API_KEY: ${{ secrets.LLM_API_KEY }} LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }} + RUNTIME: ${{ secrets.RUNTIME }} + ALLHANDS_API_KEY: ${{ secrets.ALLHANDS_API_KEY }} PYTHONPATH: "" run: | cd /tmp && python -m openhands_resolver.resolve_issue \ @@ -136,6 +142,8 @@ jobs: LLM_MODEL: ${{ secrets.LLM_MODEL }} LLM_API_KEY: ${{ secrets.LLM_API_KEY }} LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }} + RUNTIME: ${{ secrets.RUNTIME }} + ALLHANDS_API_KEY: ${{ secrets.ALLHANDS_API_KEY }} PYTHONPATH: "" run: | if [ "${{ steps.check_result.outputs.RESOLUTION_SUCCESS }}" == "true" ]; then diff --git a/openhands_resolver/resolve_issue.py b/openhands_resolver/resolve_issue.py index 288cb45..a9951d5 100644 --- a/openhands_resolver/resolve_issue.py +++ b/openhands_resolver/resolve_issue.py @@ -182,7 +182,7 @@ async def process_issue( config = AppConfig( default_agent="CodeActAgent", - runtime='eventstream', + runtime=os.environ.get('RUNTIME', 'eventstream'), max_budget_per_task=4, max_iterations=max_iterations, sandbox=SandboxConfig( @@ -191,6 +191,7 @@ async def process_issue( use_host_network=False, # large enough timeout, since some testcases take very long to run timeout=300, + api_key=os.environ.get('ALLHANDS_API_KEY', None), ), # do not mount workspace workspace_base=workspace_base, diff --git a/tests/test_remote_runtime.py b/tests/test_remote_runtime.py new file mode 100644 index 0000000..1b0eeea --- /dev/null +++ b/tests/test_remote_runtime.py @@ -0,0 +1,76 @@ +import os +import pytest +from openhands_resolver.resolve_issue import process_issue +from openhands_resolver.github_issue import GithubIssue +from openhands.core.config import LLMConfig + + +@pytest.fixture +def mock_env_vars(monkeypatch): + monkeypatch.setenv('RUNTIME', 'remote') + monkeypatch.setenv('ALLHANDS_API_KEY', 'test-api-key') + + +@pytest.fixture +def mock_issue(): + return GithubIssue( + number=1, + title="Test Issue", + body="Test body", + labels=["test"], + state="open", + created_at="2024-01-01T00:00:00Z", + updated_at="2024-01-01T00:00:00Z", + html_url="https://github.com/test/test/issues/1", + comments=[], + head_branch=None, + base_branch=None, + review_comments=[], + owner="test", + repo="test", + ) + + +@pytest.mark.asyncio +async def test_remote_runtime_config(mock_env_vars, mock_issue, tmp_path): + # Create a mock LLM config + llm_config = LLMConfig( + model="test-model", + api_key="test-key", + base_url="http://test.com", + ) + + # Create output directory + output_dir = str(tmp_path) + os.makedirs(output_dir, exist_ok=True) + os.makedirs(os.path.join(output_dir, "repo"), exist_ok=True) + + # Mock issue handler + class MockIssueHandler: + issue_type = "issue" + + def get_instruction(self, issue, prompt_template, repo_instruction): + return "test instruction", [] + + def guess_success(self, issue, history, llm_config): + return True, None, "test explanation" + + try: + await process_issue( + mock_issue, + "test-commit", + 1, + llm_config, + output_dir, + "test-image", + "test-prompt", + MockIssueHandler(), + None, + True, + ) + + # The test will fail before this point due to connection errors, + # but we can verify the config was set up correctly + except Exception as e: + # We expect a connection error since we're not actually connecting to a remote runtime + assert "Failed to connect" in str(e) or "Connection refused" in str(e)