Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexCuadron committed Oct 31, 2024
2 parents 619bbf1 + 9442e4f commit 65ec945
Show file tree
Hide file tree
Showing 27 changed files with 319 additions and 306 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/ghcr-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -399,3 +399,49 @@ jobs:
run: |
echo "Some runtime tests failed or were cancelled"
exit 1
update_pr_description:
name: Update PR Description
if: github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork
needs: [ghcr_build_runtime]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Get short SHA
id: short_sha
run: echo "SHORT_SHA=$(echo ${{ github.event.pull_request.head.sha }} | cut -c1-7)" >> $GITHUB_OUTPUT

- name: Update PR Description
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
SHORT_SHA: ${{ steps.short_sha.outputs.SHORT_SHA }}
run: |
echo "updating PR description"
DOCKER_RUN_COMMAND="docker run -it --rm \
-p 3000:3000 \
-v /var/run/docker.sock:/var/run/docker.sock \
--add-host host.docker.internal:host-gateway \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/all-hands-ai/runtime:$SHORT_SHA-nikolaik \
--name openhands-app-$SHORT_SHA \
ghcr.io/all-hands-ai/runtime:$SHORT_SHA"
PR_BODY=$(gh pr view $PR_NUMBER --json body --jq .body)
if echo "$PR_BODY" | grep -q "To run this PR locally, use the following command:"; then
UPDATED_PR_BODY=$(echo "${PR_BODY}" | sed -E "s|docker run -it --rm.*|$DOCKER_RUN_COMMAND|")
else
UPDATED_PR_BODY="${PR_BODY}
---
To run this PR locally, use the following command:
\`\`\`
$DOCKER_RUN_COMMAND
\`\`\`"
fi
echo "updated body: $UPDATED_PR_BODY"
gh pr edit $PR_NUMBER --body "$UPDATED_PR_BODY"
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,26 @@ Learn more at [docs.all-hands.dev](https://docs.all-hands.dev), or jump to the [

## ⚡ Quick Start

The easiest way to run OpenHands is in Docker. You can change `WORKSPACE_BASE` below to
point OpenHands to existing code that you'd like to modify.

The easiest way to run OpenHands is in Docker.
See the [Installation](https://docs.all-hands.dev/modules/usage/installation) guide for
system requirements and more information.

```bash
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.11-nikolaik
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.12-nikolaik

docker run -it --rm --pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.11-nikolaik \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.12-nikolaik \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app \
docker.all-hands.dev/all-hands-ai/openhands:0.11
docker.all-hands.dev/all-hands-ai/openhands:0.12
```

You'll find OpenHands running at [http://localhost:3000](http://localhost:3000)!

You'll need a model provider and API key.
[Anthropic's Claude 3.5 Sonnet (`anthropic/claude-3-5-sonnet-20241022`)](https://www.anthropic.com/api)
Finally, you'll need a model provider and API key.
[Anthropic's Claude 3.5 Sonnet](https://www.anthropic.com/api) (`anthropic/claude-3-5-sonnet-20241022`)
works best, but you have [many options](https://docs.all-hands.dev/modules/usage/llms).

---
Expand Down
4 changes: 2 additions & 2 deletions docs/modules/usage/how-to/cli-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ LLM_API_KEY="sk_test_12345"
```bash
docker run -it \
--pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.12-nikolaik \
-e SANDBOX_USER_ID=$(id -u) \
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
-e LLM_API_KEY=$LLM_API_KEY \
Expand All @@ -58,7 +59,7 @@ docker run -it \
-v /var/run/docker.sock:/var/run/docker.sock \
--add-host host.docker.internal:host-gateway \
--name openhands-app-$(date +%Y%m%d%H%M%S) \
docker.all-hands.dev/all-hands-ai/openhands:0.11 \
docker.all-hands.dev/all-hands-ai/openhands:0.12 \
python -m openhands.core.cli
```

Expand Down Expand Up @@ -107,4 +108,3 @@ Expected Output:
```bash
🤖 An error occurred. Please try again.
```

4 changes: 2 additions & 2 deletions docs/modules/usage/how-to/headless-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ LLM_API_KEY="sk_test_12345"
```bash
docker run -it \
--pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.12-nikolaik \
-e SANDBOX_USER_ID=$(id -u) \
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
-e LLM_API_KEY=$LLM_API_KEY \
Expand All @@ -52,7 +53,6 @@ docker run -it \
-v /var/run/docker.sock:/var/run/docker.sock \
--add-host host.docker.internal:host-gateway \
--name openhands-app-$(date +%Y%m%d%H%M%S) \
docker.all-hands.dev/all-hands-ai/openhands:0.11 \
docker.all-hands.dev/all-hands-ai/openhands:0.12 \
python -m openhands.core.main -t "write a bash script that prints hi"
```

6 changes: 3 additions & 3 deletions docs/modules/usage/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
The easiest way to run OpenHands is in Docker.

```bash
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.11-nikolaik
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.12-nikolaik

docker run -it --rm --pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.11-nikolaik \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.12-nikolaik \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app \
docker.all-hands.dev/all-hands-ai/openhands:0.11
docker.all-hands.dev/all-hands-ai/openhands:0.12
```

You can also run OpenHands in a scriptable [headless mode](https://docs.all-hands.dev/modules/usage/how-to/headless-mode), as an [interactive CLI](https://docs.all-hands.dev/modules/usage/how-to/cli-mode), or using the [OpenHands GitHub Action](https://docs.all-hands.dev/modules/usage/how-to/github-action).
Expand Down
2 changes: 1 addition & 1 deletion evaluation/swe_bench/eval_infer.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def process_instance(
# Create a directory structure that matches the expected format
# NOTE: this is a hack to make the eval report format consistent
# with the original SWE-Bench eval script
log_dir = os.path.join(temp_dir, 'logs', instance_id)
log_dir = os.path.join(temp_dir, 'logs', instance_id.lower())
os.makedirs(log_dir, exist_ok=True)
test_output_path = os.path.join(log_dir, 'test_output.txt')
with open(test_output_path, 'w') as f:
Expand Down
2 changes: 1 addition & 1 deletion evaluation/swe_bench/run_infer.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def get_instance_docker_image(instance_id: str) -> str:
image_name = image_name.replace(
'__', '_s_'
) # to comply with docker image naming convention
return DOCKER_IMAGE_PREFIX.rstrip('/') + '/' + image_name
return (DOCKER_IMAGE_PREFIX.rstrip('/') + '/' + image_name).lower()


def get_config(
Expand Down
65 changes: 3 additions & 62 deletions frontend/__tests__/components/feedback-form.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ import { FeedbackForm } from "#/components/feedback-form";

describe("FeedbackForm", () => {
const user = userEvent.setup();
const onSubmitMock = vi.fn();
const onCloseMock = vi.fn();

afterEach(() => {
vi.clearAllMocks();
});

it("should render correctly", () => {
render(<FeedbackForm onSubmit={onSubmitMock} onClose={onCloseMock} />);
render(<FeedbackForm polarity="positive" onClose={onCloseMock} />);

screen.getByLabelText("Email");
screen.getByLabelText("Private");
Expand All @@ -24,7 +23,7 @@ describe("FeedbackForm", () => {
});

it("should switch between private and public permissions", async () => {
render(<FeedbackForm onSubmit={onSubmitMock} onClose={onCloseMock} />);
render(<FeedbackForm polarity="positive" onClose={onCloseMock} />);
const privateRadio = screen.getByLabelText("Private");
const publicRadio = screen.getByLabelText("Public");

Expand All @@ -40,69 +39,11 @@ describe("FeedbackForm", () => {
expect(publicRadio).not.toBeChecked();
});

it("should call onSubmit when the form is submitted", async () => {
render(<FeedbackForm onSubmit={onSubmitMock} onClose={onCloseMock} />);
const email = screen.getByLabelText("Email");

await user.type(email, "[email protected]");
await user.click(screen.getByRole("button", { name: "Submit" }));

expect(onSubmitMock).toHaveBeenCalledWith("private", "[email protected]"); // private is the default value
});

it("should not call onSubmit when the email is invalid", async () => {
render(<FeedbackForm onSubmit={onSubmitMock} onClose={onCloseMock} />);
const email = screen.getByLabelText("Email");
const submitButton = screen.getByRole("button", { name: "Submit" });

await user.click(submitButton);

expect(onSubmitMock).not.toHaveBeenCalled();

await user.type(email, "test");
await user.click(submitButton);

expect(onSubmitMock).not.toHaveBeenCalled();
});

it("should submit public permissions when the public radio is checked", async () => {
render(<FeedbackForm onSubmit={onSubmitMock} onClose={onCloseMock} />);
const email = screen.getByLabelText("Email");
const publicRadio = screen.getByLabelText("Public");

await user.type(email, "[email protected]");
await user.click(publicRadio);
await user.click(screen.getByRole("button", { name: "Submit" }));

expect(onSubmitMock).toHaveBeenCalledWith("public", "[email protected]");
});

it("should call onClose when the close button is clicked", async () => {
render(<FeedbackForm onSubmit={onSubmitMock} onClose={onCloseMock} />);
render(<FeedbackForm polarity="positive" onClose={onCloseMock} />);
await user.click(screen.getByRole("button", { name: "Cancel" }));

expect(onSubmitMock).not.toHaveBeenCalled();
expect(onCloseMock).toHaveBeenCalled();
});

it("should disable the buttons if isSubmitting is true", () => {
const { rerender } = render(
<FeedbackForm onSubmit={onSubmitMock} onClose={onCloseMock} />,
);
const submitButton = screen.getByRole("button", { name: "Submit" });
const cancelButton = screen.getByRole("button", { name: "Cancel" });

expect(submitButton).not.toBeDisabled();
expect(cancelButton).not.toBeDisabled();

rerender(
<FeedbackForm
onSubmit={onSubmitMock}
onClose={onCloseMock}
isSubmitting
/>,
);
expect(submitButton).toBeDisabled();
expect(cancelButton).toBeDisabled();
});
});
4 changes: 2 additions & 2 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openhands-frontend",
"version": "0.11.0",
"version": "0.12.0",
"private": true,
"type": "module",
"engines": {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/api/open-hands.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export interface Feedback {
version: string;
email: string;
token: string;
feedback: "positive" | "negative";
polarity: "positive" | "negative";
permissions: "public" | "private";
trajectory: unknown[];
}
Expand Down
Loading

0 comments on commit 65ec945

Please sign in to comment.