Skip to content

Commit

Permalink
Merge branch 'main' into kevin
Browse files Browse the repository at this point in the history
  • Loading branch information
SmartManoj committed Oct 7, 2024
2 parents 7df9720 + 6b1f23a commit 1f6b72f
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 16 deletions.
4 changes: 2 additions & 2 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

## Contributors

We would like to thank all the [contributors](https://github.com/All-Hands-AI/OpenHands/graphs/contributors) who have helped make OpenHands possible. Your dedication and hard work are greatly appreciated.
We would like to thank all the [contributors](https://github.com/All-Hands-AI/OpenHands/graphs/contributors) who have helped make OpenHands possible. We greatly appreciate your dedication and hard work.

## Open Source Projects

OpenHands includes and adapts the following open source projects. We are grateful for their contributions to the open source community:

#### [SWE Agent](https://github.com/princeton-nlp/swe-agent)
- License: MIT License
- Description: Adapted for use in OpenHands's agenthub
- Description: Adapted for use in OpenHands's agent hub

#### [Aider](https://github.com/paul-gauthier/aider)
- License: Apache License 2.0
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Learn more at [docs.all-hands.dev](https://docs.all-hands.dev), or jump to the [
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.

See the [Getting Started](https://docs.all-hands.dev/modules/usage/getting-started) guide for
See the [Installation](https://docs.all-hands.dev/modules/usage/installation) guide for
system requirements and more information.

```bash
Expand Down Expand Up @@ -124,7 +124,7 @@ You'll need a model provider and API key. One option that works well: [Claude 3.
You can also run OpenHands in a scriptable [headless mode](https://docs.all-hands.dev/modules/usage/how-to/headless-mode),
or as an [interactive CLI](https://docs.all-hands.dev/modules/usage/how-to/cli-mode).

Visit [Getting Started](https://docs.all-hands.dev/modules/usage/getting-started) for more information and setup instructions.
Visit [Installation](https://docs.all-hands.dev/modules/usage/installation) for more information and setup instructions.

If you want to modify the Kevin source code, check out [Development.md](https://github.com/SmartManoj/Kevin/blob/main/Development.md).

Expand Down
6 changes: 3 additions & 3 deletions agenthub/browsing_agent/response_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,17 @@ def parse(self, action_str: str) -> Action:
assert (
self.action_str is not None
), 'self.action_str should not be None when parse is called'
action_cmd = self.action_str.group(1).strip()
browser_actions = self.action_str.group(1).strip()
thought = action_str.replace(self.action_str.group(0), '').strip()
msg_content = ''
for sub_action in action_cmd.split('\n'):
for sub_action in browser_actions.split('\n'):
if 'send_msg_to_user(' in sub_action:
tree = ast.parse(sub_action)
args = tree.body[0].value.args # type: ignore
msg_content = args[0].value

return BrowseInteractiveAction(
browser_actions=action_cmd,
browser_actions=browser_actions,
thought=thought,
browsergym_send_msg_to_user=msg_content,
)
20 changes: 13 additions & 7 deletions docs/modules/usage/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,30 @@ engineering tasks without any guidance. So it's important to get a feel for what
does well, and where it might need some help.

## Hello World

The first thing you might want to try is a simple "hello world" example.
This can be more complicated than it sounds!

Try prompting the agent with:
> Please write a bash script hello.sh that prints "hello world!"
You should see that the agent not only writes the script--it sets the correct
You should see that the agent not only writes the script, it sets the correct
permissions and runs the script to check the output.

You can continue prompting the agent to refine your code. This is a great way to
work with agents--start simple, and iterate.
work with agents. Start simple, and iterate.

> Please modify hello.sh so that it accepts a name as the first argument, but defaults to "world"
You can also work in any language you need--though the agent might need to spend some
You can also work in any language you need, though the agent might need to spend some
time setting up its environment!

> Please convert hello.sh to a Ruby script, and run it
## Building from scratch
Agents do exceptionally well at "greenfield" tasks--tasks where they don't need
any context about an existing codebase, and they can just start from scratch.
## Building From Scratch

Agents do exceptionally well at "greenfield" tasks (tasks where they don't need
any context about an existing codebase) and they can just start from scratch.

It's best to start with a simple task, and then iterate on it. It's also best to be
as specific as possible about what you want, what the tech stack should be, etc.
Expand All @@ -51,7 +53,8 @@ You can ask the agent to commit and push for you:
> Please commit the changes and push them to a new branch called "feature/due-dates"

## Adding new code
## Adding New Code

OpenHands can also do a great job adding new code to an existing code base.

For example, you can ask OpenHands to add a new GitHub action to your project
Expand All @@ -70,6 +73,7 @@ and more accurately. And it'll cost you fewer tokens!
> directory. It should use the existing Widget component.
## Refactoring

OpenHands does great at refactoring existing code, especially in small chunks.
You probably don't want to try rearchitecting your whole codebase, but breaking up
long files and functions, renaming variables, etc. tend to work very well.
Expand All @@ -81,6 +85,7 @@ long files and functions, renaming variables, etc. tend to work very well.
> Please break ./api/routes.js into separate files for each route
## Bug Fixes

OpenHands can also help you track down and fix bugs in your code. But, as any
developer knows, bug fixing can be extremely tricky, and often OpenHands will need more context.
It helps if you've diagnosed the bug, but want OpenHands to figure out the logic.
Expand All @@ -95,6 +100,7 @@ You can ask the agent to write a new test, and then iterate until it fixes the b
> The `hello` function crashes on the empty string. Please write a test that reproduces this bug, then fix the code so it passes.
## More

OpenHands is capable of helping out on just about any coding task. But it takes some practice
to get the most out of it. Remember to:
* Keep your tasks small
Expand Down
6 changes: 4 additions & 2 deletions openhands/llm/async_llm.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import asyncio
from functools import partial

from litellm import completion as litellm_acompletion
from litellm import acompletion as litellm_acompletion

from openhands.core.exceptions import UserCancelledError
from openhands.core.logger import openhands_logger as logger
Expand Down Expand Up @@ -40,7 +40,7 @@ def __init__(self, *args, **kwargs):
retry_multiplier=self.config.retry_multiplier,
)
async def async_completion_wrapper(*args, **kwargs):
"""Wrapper for the litellm acompletion function."""
"""Wrapper for the litellm acompletion function that adds logging and cost tracking."""
messages: list[Message] | Message = []

# some callers might send the model and messages directly
Expand Down Expand Up @@ -84,6 +84,8 @@ async def check_stopped():

message_back = resp['choices'][0]['message']['content']
self.log_response(message_back)

# log costs and tokens used
self._post_completion(resp)

# We do not support streaming in this method, thus return resp
Expand Down
2 changes: 2 additions & 0 deletions openhands/llm/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
# tuple of exceptions to retry on
LLM_RETRY_EXCEPTIONS: tuple[type[Exception], ...] = (
APIConnectionError,
# FIXME: APIError is useful on 502 from a proxy for example,
# but it also retries on other errors that are permanent
APIError,
InternalServerError,
RateLimitError,
Expand Down
54 changes: 54 additions & 0 deletions tests/unit/test_browsing_agent_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import pytest

from agenthub.browsing_agent.response_parser import (
BrowseInteractiveAction,
BrowsingResponseParser,
)


@pytest.mark.parametrize(
'action_str, expected',
[
("click('81'", "click('81')```"),
(
'"We need to search the internet\n```goto("google.com")',
'"We need to search the internet\n```goto("google.com"))```',
),
("```click('81'", "```click('81')```"),
("click('81')", "click('81'))```"),
],
)
def test_parse_response(action_str: str, expected: str) -> None:
# BrowsingResponseParser.parse_response
parser = BrowsingResponseParser()
response = {'choices': [{'message': {'content': action_str}}]}
result = parser.parse_response(response)
assert result == expected


@pytest.mark.parametrize(
'action_str, expected_browser_actions, expected_thought, expected_msg_content',
[
("click('81')```", "click('81')", '', ''),
("```click('81')```", "click('81')", '', ''),
(
"We need to perform a click\n```click('81')",
"click('81')",
'We need to perform a click',
'',
),
],
)
def test_parse_action(
action_str: str,
expected_browser_actions: str,
expected_thought: str,
expected_msg_content: str,
) -> None:
# BrowsingResponseParser.parse_action
parser = BrowsingResponseParser()
action = parser.parse_action(action_str)
assert isinstance(action, BrowseInteractiveAction)
assert action.browser_actions == expected_browser_actions
assert action.thought == expected_thought
assert action.browsergym_send_msg_to_user == expected_msg_content

0 comments on commit 1f6b72f

Please sign in to comment.