Compare commits

..

46 Commits

Author SHA1 Message Date
openhands 539d620a46 Add email validation in user settings 2025-06-06 17:14:43 +00:00
chuckbutkus 6cd7856659 Merge branch 'main' into allow-email-change 2025-06-06 12:03:05 -04:00
chuckbutkus 5dc7ca062b Merge branch 'main' into allow-email-change 2025-06-06 01:12:36 -04:00
Chuck Butkus 18e4054fc5 Add interceptor to redirect on email not verified error 2025-06-06 00:53:40 -04:00
chuckbutkus f541c34e85 Merge branch 'main' into allow-email-change 2025-06-05 21:13:36 -04:00
Chuck Butkus 313276207b Update to use toast messages 2025-06-05 15:46:36 -04:00
Chuck Butkus 7e34240d49 Fix email input box 2025-06-05 15:33:59 -04:00
chuckbutkus 76be0ffff9 Merge branch 'main' into allow-email-change 2025-06-05 15:26:33 -04:00
Chuck Butkus 60eb68bd91 User setting refactor 2025-06-05 15:23:04 -04:00
Chuck Butkus 686eb45fae User setting refactor 2025-06-05 15:23:04 -04:00
chuckbutkus 8566cd6ed2 Merge branch 'main' into allow-email-change 2025-06-05 12:19:24 -04:00
chuckbutkus 854e926bac Merge branch 'main' into allow-email-change 2025-06-04 23:15:49 -04:00
openhands f981a8a254 Update email placeholder to show 'Loading...' instead of 'Email not available' 2025-06-05 03:00:40 +00:00
openhands 3f47187f2f Update buttons to have black text when disabled 2025-06-05 02:43:02 +00:00
openhands 19c4296b07 Update button styles to match the Launch button style 2025-06-05 02:31:05 +00:00
Chuck Butkus 0929936045 Fix lint 2025-06-04 22:10:41 -04:00
openhands 6765673523 Remove default value for email verification restriction message 2025-06-05 01:56:02 +00:00
openhands 846999202d Update email verification success message and add translations 2025-06-05 01:53:35 +00:00
openhands 523d2ff170 Add background polling for email verification status on user settings page 2025-06-05 01:34:56 +00:00
chuckbutkus edf2269f13 Merge branch 'main' into allow-email-change 2025-06-04 17:21:14 -04:00
openhands a0bdd4101c Fix settings-with-payment test by adding user settings route and mocking email verification 2025-06-04 19:50:51 +00:00
chuckbutkus c7ca81f85c Merge branch 'main' into allow-email-change 2025-06-04 15:28:13 -04:00
chuckbutkus bff22652cb Merge branch 'main' into allow-email-change 2025-06-04 14:27:26 -04:00
Chuck Butkus 330d5a75e7 Fix lint errors 2025-06-04 12:57:46 -04:00
Chuck Butkus 42885c0288 Fix lint errors 2025-06-04 12:48:23 -04:00
Chuck Butkus 8805f34af0 Remove duplication 2025-06-04 02:38:06 -04:00
openhands 45bb6877e6 Update remaining files for EMAIL_VERIFIED restriction 2025-06-04 06:25:38 +00:00
openhands 703efd17ab Restrict app to only show user settings page when EMAIL_VERIFIED is false 2025-06-04 06:17:37 +00:00
openhands b8884ed447 Add email verification UI improvements: hide resend button when verified and show warning message when not verified 2025-06-04 01:55:52 +00:00
Chuck Butkus 8cfac66cc9 Another email_verified change 2025-06-03 21:40:03 -04:00
Chuck Butkus bcdec805e2 Add email_verified to settings 2025-06-03 21:35:01 -04:00
Chuck Butkus 2138eeb556 Update 2025-06-03 01:15:17 -04:00
openhands e00b00b372 Set withCredentials only in user-settings.tsx instead of globally 2025-06-03 04:36:45 +00:00
openhands 5f1f3b1e2d Enable withCredentials to allow cookies to be set from API responses 2025-06-03 04:35:17 +00:00
openhands 45ffac0b78 Add translations for resend verification email functionality 2025-06-02 22:09:42 +00:00
openhands 70a8e1bc0a Move save button to be before resend verification button on the same line 2025-06-02 21:40:22 +00:00
openhands e74b354137 Add resend verification email button to user settings 2025-06-02 21:06:57 +00:00
Chuck Butkus 56ed63088f Update 2025-06-02 16:23:01 -04:00
openhands 489e32c2c0 Fix email update to use /api/settings endpoint 2025-05-31 19:10:03 +00:00
openhands c189012f0a Fix email update to use query parameter instead of form data 2025-05-31 19:05:02 +00:00
openhands 2407420e17 Make email field editable and add save button in user settings 2025-05-31 18:59:14 +00:00
chuckbutkus bb0c47c41a Merge branch 'main' into display-email 2025-05-31 01:14:24 -04:00
Chuck Butkus 83e5276de5 Update User Setting tab 2025-05-31 01:13:38 -04:00
openhands 816082a55b Update User tab to display email from settings instead of git user 2025-05-31 04:12:04 +00:00
Chuck Butkus 82d72b145d Add email to Setting class 2025-05-30 23:59:47 -04:00
Chuck Butkus f8c3470c91 Add get_user_email from UserAuth 2025-05-30 15:43:08 -04:00
42 changed files with 212 additions and 723 deletions
-1
View File
@@ -12,5 +12,4 @@
"ghcr.io/devcontainers/features/node:1": {},
},
"postCreateCommand": ".devcontainer/setup.sh",
"runArgs": ["--network=host"],
}
+1 -1
View File
@@ -5,7 +5,7 @@
/frontend/ @rbren @amanape
# Evaluation code owners
/evaluation/ @xingyaoww @neubig
/evaluation/ @xingyaoww @neubig
# Documentation code owners
/docs/ @mamoodi
+1
View File
@@ -38,6 +38,7 @@
]
},
"usage/cloud/cloud-ui",
"usage/cloud/cloud-issue-resolver",
"usage/cloud/cloud-api"
]
},
+33
View File
@@ -0,0 +1,33 @@
---
title: Cloud Issue Resolver
description: The Cloud Issue Resolver automates code fixes and provides intelligent assistance for your repositories on GitHub.
---
## Setup
The Cloud Issue Resolver is available automatically when you grant OpenHands Cloud repository access:
- [GitHub repository access](./github-installation#adding-repository-access)
## Usage
After granting OpenHands Cloud repository access, you can use the Cloud Issue Resolver on issues and pull requests in your repositories.
### Working with Issues
On your repository, label an issue with `openhands` or add a message starting with
`@openhands`. OpenHands will:
1. Comment on the issue to let you know it is working on it
- You can click on the link to track the progress on OpenHands Cloud
2. Open a pull request if it determines that the issue has been successfully resolved
3. Comment on the issue with a summary of the performed tasks and a link to the PR
### Working with Pull Requests
To get OpenHands to work on pull requests, mention `@openhands` in comments to:
- Ask questions
- Request updates
- Get code explanations
OpenHands will:
1. Comment to let you know it is working on it
2. Perform the requested task
+15 -23
View File
@@ -1,36 +1,28 @@
---
title: Cloud UI
description: The Cloud UI provides a web interface for interacting with OpenHands. This page explains how to use the
OpenHands Cloud UI.
description: The Cloud UI provides a web interface for interacting with OpenHands AI. This page explains how to access and use the OpenHands Cloud UI.
---
## Landing Page
The landing page is where you can:
## Accessing the UI
- [Add GitHub repository access](/usage/cloud/github-installation#adding-github-repository-access) to OpenHands.
- [Select a GitHub repo](/usage/cloud/github-installation#working-with-github-repos-in-openhands-cloud) or
[a GitLab repo](/usage/cloud/gitlab-installation#working-with-gitlab-repos-in-openhands-cloud) to start working on.
- See `Suggested Tasks` for repositories that OpenHands has access to.
- Launch an empty conversation using `Launch from Scratch`.
The OpenHands Cloud UI can be accessed at [app.all-hands.dev](https://app.all-hands.dev). You'll need to sign in with your GitHub or GitLab account to access the interface.
## Settings
The Settings page allows you to:
- [Configure GitHub repository access](/usage/cloud/github-installation#modifying-repository-access) for OpenHands.
- Set application settings like your preferred language, notifications and other preferences.
- Add credits to your account.
- Generate custom secrets.
- Create API keys to work with OpenHands programmatically.
## Key Features
For an overview of the key features available inside a conversation, please refer to the [Key Features](../key-features)
section of the documentation.
For detailed information about the features available in the OpenHands Cloud UI, please refer to the [Key Features](../key-features) section of the documentation.
## Settings
The settings page allows you to:
- Configure your account preferences.
- Manage repository access.
- Generate API keys for programmatic access.
- Generate custom secrets for the agent.
## Next Steps
- [Install GitHub Integration](/usage/cloud/github-installation) to use OpenHands with your GitHub repositories.
- [Install GitLab Integration](/usage/cloud/gitlab-installation) to use OpenHands with your GitLab repositories.
- [Use the Cloud API](/usage/cloud/cloud-api) to programmatically interact with OpenHands.
- [Use the Cloud Issue Resolver](./cloud-issue-resolver) to automate code fixes and get assistance.
- [Learn about the Cloud API](./cloud-api) for programmatic access.
+5 -5
View File
@@ -1,7 +1,7 @@
---
title: GitHub Integration
description: This guide walks you through the process of installing OpenHands Cloud for your GitHub repositories. Once
set up, it will allow OpenHands to work with your GitHub repository through the Cloud UI or straight from GitHub!
set up, it will allow OpenHands to work with your GitHub repository through the Cloud UI or straight from GitHub issues!
---
## Prerequisites
@@ -37,11 +37,11 @@ You can modify GitHub repository access at any time by:
- Selecting `Add GitHub repos` on the landing page or
- Visiting the Settings page and selecting `Configure GitHub Repositories` under the `Git` tab
## Working With GitHub Repos in Openhands Cloud
## Working With Github Repos in Openhands Cloud
Once you've granted GitHub repository access, you can start working with your GitHub repository. Use the `select a repo`
and `select a branch` dropdowns to select the appropriate repository and branch you'd like OpenHands to work on. Then
click on `Launch` to start the conversation!
click on `Launch` to start the session!
![Connect Repo](/static/img/connect-repo.png)
@@ -67,5 +67,5 @@ To get OpenHands to work on pull requests, mention `@openhands` in the comments
## Next Steps
- [Learn about the Cloud UI](/usage/cloud/cloud-ui).
- [Use the Cloud API](/usage/cloud/cloud-api) to programmatically interact with OpenHands.
- [Access the Cloud UI](./cloud-ui) to interact with the web interface
- [Use the Cloud API](./cloud-api) to programmatically interact with OpenHands
+10 -12
View File
@@ -1,25 +1,23 @@
---
title: GitLab Integration
description: This guide walks you through the process of installing OpenHands Cloud for your GitLab repositories. Once
set up, it will allow OpenHands to work with your GitLab repository.
description: This guide walks you through the process of installing and configuring OpenHands Cloud for your GitLab repositories.
---
## Prerequisites
- Signed in to [OpenHands Cloud](https://app.all-hands.dev) with [a GitLab account](/usage/cloud/openhands-cloud).
- A GitLab account
- Access to OpenHands Cloud
## Adding GitLab Repository Access
## Installation Steps
Upon signing into OpenHands Cloud with a GitLab account, OpenHands will have access to your repositories.
1. Log in to [OpenHands Cloud](https://app.all-hands.dev)
2. If you haven't connected your GitLab account yet:
- Click on `Log in with GitLab`
- Authorize the OpenHands application
## Working With GitLab Repos in Openhands Cloud
After signing in with a Gitlab account, use the `select a repo` and `select a branch` dropdowns to select the
appropriate repository and branch you'd like OpenHands to work on. Then click on `Launch` to start the conversation!
![Connect Repo](/static/img/connect-repo.png)
## Next Steps
- [Learn about the Cloud UI](/usage/cloud/cloud-ui).
- [Use the Cloud API](/usage/cloud/cloud-api) to programmatically interact with OpenHands.
- [Access the Cloud UI](./cloud-ui) to interact with the web interface
- [Use the Cloud API](./cloud-api) to programmatically interact with OpenHands
+5 -5
View File
@@ -14,13 +14,13 @@ You'll be prompted to connect with your GitHub or GitLab account:
2. Review the permissions requested by OpenHands and authorize the application.
- OpenHands will require certain permissions from your account. To read more about these permissions,
you can click the `Learn more` link on the authorization page.
3. Review and accept the `terms of service` and select `Continue`.
## Next Steps
Once you've connected your account, you can:
- [Install GitHub Integration](/usage/cloud/github-installation) to use OpenHands with your GitHub repositories.
- [Install GitLab Integration](/usage/cloud/gitlab-installation) to use OpenHands with your GitLab repositories.
- [Learn about the Cloud UI](/usage/cloud/cloud-ui).
- [Use the Cloud API](/usage/cloud/cloud-api) to programmatically interact with OpenHands.
- [Install GitHub Integration](./github-installation) to use OpenHands with your GitHub repositories
- [Install GitLab Integration](./gitlab-installation) to use OpenHands with your GitLab repositories
- [Access the Cloud UI](./cloud-ui) to interact with the web interface
- [Use the Cloud API](./cloud-api) to programmatically interact with OpenHands
- [Set up the Cloud Issue Resolver](./cloud-issue-resolver) to automate code fixes and provide intelligent assistance
+7 -146
View File
@@ -5,111 +5,26 @@ description: Keyword-triggered microagents provide OpenHands with specific instr
## Usage
Keyword-triggered microagents are only loaded when a prompt includes one of the trigger words. There are two types of keyword-triggered microagents:
1. **Standard Keyword Microagents**: Triggered by keywords embedded in text
2. **Command-Style Microagents**: Triggered by command-style inputs (e.g., `/fix_test`) that can prompt for user input
Additionally, there's a special type of microagent that's always active:
3. **Repository Microagents**: Always active for a specific repository, providing repository-specific context and tools
These microagents are only loaded when a prompt includes one of the trigger words.
## Frontmatter Syntax
Frontmatter is required for keyword-triggered microagents. It must be placed at the top of the file,
above the guidelines. Enclose the frontmatter in triple dashes (---).
above the guidelines.
### Standard Keyword Microagents
For standard keyword microagents, include the following fields:
Enclose the frontmatter in triple dashes (---) and include the following fields:
| Field | Description | Required | Default |
|------------|--------------------------------------------------|----------|------------------|
| `name` | The name of the microagent | No | Filename |
| `type` | The type of microagent (`knowledge`) | No | Inferred |
| `triggers` | A list of keywords that activate the microagent. | Yes | None |
| `agent` | The agent this microagent applies to. | No | 'CodeActAgent' |
### Command-Style Microagents
For command-style microagents that require user input, include the following fields:
## Example
| Field | Description | Required | Default |
|------------|------------------------------------------------------------|----------|------------------|
| `name` | The name of the microagent | No | Filename |
| `type` | The type of microagent (`task`) | No | Inferred |
| `triggers` | A list of command triggers (e.g., `/fix_test`) | No | `/[name]` |
| `inputs` | A list of input variables the microagent requires | Yes | None |
### Repository Microagents
Repository microagents are always active for a specific repository. They provide repository-specific context and tools.
| Field | Description | Required | Default |
|------------|------------------------------------------------------------|----------|------------------|
| `name` | The name of the microagent | No | Filename |
| `type` | The type of microagent (`repo`) | No | Inferred |
#### Repository Microagent Example
Here's an example of a repository microagent:
```yaml
---
# The type field is optional and will be inferred as 'repo' when no triggers are present
---
# Repository Guidelines
This repository follows these coding standards:
1. Use PEP 8 for Python code
2. Use ESLint for JavaScript code
3. Write unit tests for all new features
Keyword-triggered microagent file example located at `.openhands/microagents/yummy.md`:
```
This microagent is always active when working with the repository and provides repository-specific guidelines.
### MCP Tools Support
Microagents can also provide additional MCP (Model-Code-Prompt) tools to the agent. This is useful for extending the agent's capabilities with custom tools.
| Field | Description | Required | Default |
|--------------|-----------------------------------------------------------|----------|------------------|
| `mcp_tools` | Configuration for additional MCP tools | No | None |
#### MCP Tools Example
Here's an example of a microagent that provides an additional MCP tool (the `fetch` tool for accessing web content):
```yaml
---
# The type field is optional and will be inferred as 'repo' when no triggers are present
mcp_tools:
stdio_servers:
- name: "fetch"
command: uvx
args:
- mcp-server-fetch
---
```
This microagent is a repository microagent (always active) that adds the `fetch` tool to the agent's capabilities.
Each input in the `inputs` list requires:
| Field | Description | Required |
|---------------|--------------------------------------------------|----------|
| `name` | The name of the input variable | Yes |
| `description` | A description of what the input should contain | Yes |
## Examples
### Standard Keyword Microagent Example
Standard keyword microagent file example located at `.openhands/microagents/yummy.md`:
```yaml
---
# The type field is optional and will be inferred as 'knowledge' when triggers are present
triggers:
- yummyhappy
- happyyummy
@@ -118,58 +33,4 @@ triggers:
The user has said the magic word. Respond with "That was delicious!"
```
### Command-Style Microagent Example
Command-style microagent file example located at `.openhands/microagents/fix_test.md`:
```yaml
---
# The type field is optional and will be inferred as 'task' when inputs are present
triggers:
- /fix_test
inputs:
- name: BRANCH_NAME
description: "Branch for the agent to work on"
- name: TEST_COMMAND_TO_RUN
description: "The test command you want the agent to work on. For example, `pytest tests/unit/test_bash_parsing.py`"
- name: FUNCTION_TO_FIX
description: "The name of function to fix"
- name: FILE_FOR_FUNCTION
description: "The path of the file that contains the function"
---
Can you check out branch "{{ BRANCH_NAME }}", and run {{ TEST_COMMAND_TO_RUN }}.
Help me fix these tests to pass by fixing the {{ FUNCTION_TO_FIX }} function in file {{ FILE_FOR_FUNCTION }}.
PLEASE DO NOT modify the tests by yourself -- Let me know if you think some of the tests are incorrect.
```
## Using Command-Style Microagents
Command-style microagents are designed to streamline common development tasks by providing structured templates for specific operations. They are triggered using a command-style format and will prompt the user for any required inputs.
### How to Use
1. Type `/` in the chat input to see available command-style microagents
2. Select a microagent from the dropdown or type its name (e.g., `/fix_test`)
3. The agent will prompt you for any required inputs
4. Provide the requested information
5. The agent will execute the task with your inputs
### Template Variables
In the body of a command-style microagent, you can reference input variables using the `{{ VARIABLE_NAME }}` syntax. These will be replaced with the user-provided values when the microagent is triggered.
### Available Command-Style Microagents
OpenHands includes several built-in command-style microagents:
| Command | Description |
|----------------------|-------------------------------------------------------|
| `/fix_test` | Fix failing tests by modifying a specific function |
| `/update_test` | Update tests for a new implementation |
| `/update_pr` | Update a pull request description |
| `/address_pr_comments` | Address comments on a pull request |
| `/add_repo_instruction` | Add instructions to the repository microagent |
[See examples of microagents in the official OpenHands repository](https://github.com/All-Hands-AI/OpenHands/tree/main/microagents)
[See examples of microagents triggered by keywords in the official OpenHands repository](https://github.com/All-Hands-AI/OpenHands/tree/main/microagents)
@@ -8,10 +8,10 @@ description: Microagents are specialized prompts that enhance OpenHands with dom
Currently OpenHands supports the following types of microagents:
- [General Microagents](./microagents-repo): General guidelines for OpenHands about the repository.
- [Keyword-Triggered Microagents](./microagents-keyword): Guidelines activated by specific keywords in prompts, including command-style microagents that prompt for user inputs.
- [Keyword-Triggered Microagents](./microagents-keyword): Guidelines activated by specific keywords in prompts.
To customize OpenHands' behavior, create a .openhands/microagents/ directory in the root of your repository and
add `<microagent_name>.md` files inside. For repository-specific guidelines, you can ask OpenHands to analyze your repository and create a comprehensive `repo.md` file (see [General Microagents](./microagents-repo) for details).
add `<microagent_name>.md` files inside.
<Note>
Loaded microagents take up space in the context window.
@@ -34,7 +34,7 @@ some-repository/
Each microagent file may include frontmatter that provides additional information. In some cases, this frontmatter
is required:
| Microagent Type | Required |
|------------------------------------------------|----------|
| `General Microagents` | No |
| `Keyword-Triggered Microagents (all types)` | Yes |
| Microagent Type | Required |
|---------------------------------|----------|
| `General Microagents` | No |
| `Keyword-Triggered Microagents` | Yes |
+2 -34
View File
@@ -17,45 +17,13 @@ Frontmatter should be enclosed in triple dashes (---) and may include the follow
|-----------|-----------------------------------------|----------|----------------|
| `agent` | The agent this microagent applies to | No | 'CodeActAgent' |
## Creating a Comprehensive Repository Agent
To create an effective repository agent, you can ask OpenHands to analyze your repository with a prompt like:
## Example
General microagent file example located at `.openhands/microagents/repo.md`:
```
Please browse the repository, look at the documentation and relevant code, and understand the purpose of this repository.
Specifically, I want you to create a `.openhands/microagents/repo.md` file. This file should contain succinct information that summarizes:
1. The purpose of this repository
2. The general setup of this repo
3. A brief description of the structure of this repo
Read all the GitHub workflows under .github/ of the repository (if this folder exists) to understand the CI checks (e.g., linter, pre-commit), and include those in the repo.md file.
```
This approach helps OpenHands capture repository context efficiently, reducing the need for repeated searches during conversations and ensuring more accurate solutions.
## Example Content
A comprehensive repository agent file (`.openhands/microagents/repo.md`) should include:
```
# Repository Purpose
This project is a TODO application that allows users to track TODO items.
# Setup Instructions
To set it up, you can run `npm run build`.
# Repository Structure
- `/src`: Core application code
- `/tests`: Test suite
- `/docs`: Documentation
- `/.github`: CI/CD workflows
# CI/CD Workflows
- `lint.yml`: Runs ESLint on all JavaScript files
- `test.yml`: Runs the test suite on pull requests
# Development Guidelines
Always make sure the tests are passing before committing changes. You can run the tests by running `npm run test`.
```
+1
View File
@@ -71,6 +71,7 @@ EVAL_CONDENSER=summarizer_for_eval \
The name is up to you, but should match a name defined in your `config.toml` file. The last argument in the command specifies the condenser configuration to use. In this case, `summarizer_for_eval` is used, which refers to the LLM-based summarizing condenser as defined above.
If no condenser configuration is specified, the 'noop' condenser will be used by default, which keeps the full conversation history.
```
For other configurations specific to evaluation, such as `save_trajectory_path`, these are typically set in the `get_config` function of the respective `run_infer.py` file for each benchmark.
-1
View File
@@ -45,7 +45,6 @@ export const useSettings = () => {
// would want to show the modal immediately if the
// settings are not found
retry: (_, error) => error.status !== 404,
refetchOnWindowFocus: false,
staleTime: 1000 * 60 * 5, // 5 minutes
gcTime: 1000 * 60 * 15, // 15 minutes
enabled: !isOnTosPage && !!userIsAuthenticated,
-1
View File
@@ -567,7 +567,6 @@ export enum I18nKey {
SETTINGS$SENDING = "SETTINGS$SENDING",
SETTINGS$VERIFICATION_EMAIL_SENT = "SETTINGS$VERIFICATION_EMAIL_SENT",
SETTINGS$EMAIL_VERIFICATION_REQUIRED = "SETTINGS$EMAIL_VERIFICATION_REQUIRED",
SETTINGS$INVALID_EMAIL_FORMAT = "SETTINGS$INVALID_EMAIL_FORMAT",
SETTINGS$EMAIL_VERIFICATION_RESTRICTION_MESSAGE = "SETTINGS$EMAIL_VERIFICATION_RESTRICTION_MESSAGE",
SETTINGS$RESEND_VERIFICATION = "SETTINGS$RESEND_VERIFICATION",
SETTINGS$FAILED_TO_RESEND_VERIFICATION = "SETTINGS$FAILED_TO_RESEND_VERIFICATION",
+2 -5
View File
@@ -50,12 +50,9 @@ function EmailInputSection({
data-testid="email-input"
/>
</div>
{isEmailChanged && !isEmailValid && (
<div
className="text-red-500 text-sm mt-1"
data-testid="email-validation-error"
>
<div className="text-red-500 text-sm mt-1" data-testid="email-validation-error">
{t("SETTINGS$INVALID_EMAIL_FORMAT")}
</div>
)}
+1 -1
View File
@@ -30,7 +30,7 @@ export const TIPS: Tip[] = [
},
{
key: I18nKey.TIPS$GITHUB_HOOK,
link: "https://docs.all-hands.dev/usage/cloud/github-installation#working-on-github-issues-and-pull-requests-using-openhands",
link: "https://docs.all-hands.dev/usage/cloud/cloud-issue-resolver",
},
{
key: I18nKey.TIPS$BLOG_SIGNUP,
-3
View File
@@ -117,10 +117,7 @@ You can see an example of a repo agent in [the agent for the OpenHands repo itse
- Include repository structure details
- Specify testing and build procedures
- List environment requirements
- Document CI workflows and checks
- Include information about code quality standards
- Maintain up-to-date team practices
- Consider using OpenHands to generate a comprehensive repo.md (see [Creating a Repository Agent](#creating-a-repository-agent))
- YAML frontmatter is optional - files without frontmatter will be loaded with default settings
### Submission Process
+16 -13
View File
@@ -1,17 +1,20 @@
---
triggers:
- new agent
- new microagent
- create agent
- create an agent
- create microagent
- create a microagent
- add agent
- add an agent
- add microagent
- add a microagent
- microagent template
name: add_agent
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers:
- new agent
- new microagent
- create agent
- create an agent
- create microagent
- create a microagent
- add agent
- add an agent
- add microagent
- add a microagent
- microagent template
---
This agent helps create new microagents in the `.openhands/microagents` directory by providing guidance and templates.
@@ -35,4 +38,4 @@ For detailed information, see:
- [Microagents Overview](https://docs.all-hands.dev/usage/prompting/microagents-overview)
- [Microagents Syntax](https://docs.all-hands.dev/usage/prompting/microagents-syntax)
- [Example GitHub Microagent](https://github.com/All-Hands-AI/OpenHands/blob/main/microagents/github.md)
- [Example GitHub Microagent](https://github.com/All-Hands-AI/OpenHands/blob/main/microagents/github.md)
-61
View File
@@ -1,61 +0,0 @@
---
inputs:
- description: Branch for the agent to work on
name: REPO_FOLDER_NAME
triggers:
- /add_repo_inst
---
Please browse the current repository under /workspace/{{ REPO_FOLDER_NAME }}, look at the documentation and relevant code, and understand the purpose of this repository.
Specifically, I want you to create a `.openhands/microagents/repo.md` file. This file should contain succinct information that summarizes (1) the purpose of this repository, (2) the general setup of this repo, and (3) a brief description of the structure of this repo.
Here's an example:
```markdown
---
name: repo
type: repo
agent: CodeActAgent
---
This repository contains the code for OpenHands, an automated AI software engineer. It has a Python backend
(in the `openhands` directory) and React frontend (in the `frontend` directory).
## General Setup:
To set up the entire repo, including frontend and backend, run `make build`.
You don't need to do this unless the user asks you to, or if you're trying to run the entire application.
Before pushing any changes, you should ensure that any lint errors or simple test errors have been fixed.
* If you've made changes to the backend, you should run `pre-commit run --all-files --config ./dev_config/python/.pre-commit-config.yaml`
* If you've made changes to the frontend, you should run `cd frontend && npm run lint:fix && npm run build ; cd ..`
If either command fails, it may have automatically fixed some issues. You should fix any issues that weren't automatically fixed,
then re-run the command to ensure it passes.
## Repository Structure
Backend:
- Located in the `openhands` directory
- Testing:
- All tests are in `tests/unit/test_*.py`
- To test new code, run `poetry run pytest tests/unit/test_xxx.py` where `xxx` is the appropriate file for the current functionality
- Write all tests with pytest
Frontend:
- Located in the `frontend` directory
- Prerequisites: A recent version of NodeJS / NPM
- Setup: Run `npm install` in the frontend directory
- Testing:
- Run tests: `npm run test`
- To run specific tests: `npm run test -- -t "TestName"`
- Building:
- Build for production: `npm run build`
- Environment Variables:
- Set in `frontend/.env` or as environment variables
- Available variables: VITE_BACKEND_HOST, VITE_USE_TLS, VITE_INSECURE_SKIP_VERIFY, VITE_FRONTEND_PORT
- Internationalization:
- Generate i18n declaration file: `npm run make-i18n`
```
Now, please write a similar markdown for the current repository.
Read all the GitHub workflows under .github/ of the repository (if this folder exists) to understand the CI checks (e.g., linter, pre-commit), and include those in the repo.md file.
-15
View File
@@ -1,15 +0,0 @@
---
inputs:
- description: URL of the pull request
name: PR_URL
- description: Branch name corresponds to the pull request
name: BRANCH_NAME
triggers:
- /address_pr_comments
---
First, check the branch {{ BRANCH_NAME }} and read the diff against the main branch to understand the purpose.
This branch corresponds to this PR {{ PR_URL }}
Next, you should use the GitHub API to read the reviews and comments on this PR and address them.
+5 -2
View File
@@ -1,7 +1,10 @@
---
name: agent_memory
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers:
- /remember
type: knowledge
---
* Repository memory: Use .openhands/microagents/repo.md under each repository root to store and access important information.
@@ -26,4 +29,4 @@ type: knowledge
- If you've only explored a portion of the codebase, clearly note this limitation in the repository structure documentation
- If you don't know the essential commands for working with the repository, such as lint or typecheck, ask the user and suggest adding them to repo.md for future reference (with permission)
When you receive this message, please review and summarize your recent actions and observations, then present a list of valuable information that should be saved in repo.md to the user.
When you receive this message, please review and summarize your recent actions and observations, then present a list of valuable information that should be saved in repo.md to the user.
+12 -6
View File
@@ -1,9 +1,15 @@
---
# This is a repo microagent that is always activated
# to include necessary default tools implemented with MCP
name: default-tools
type: repo
version: 1.0.0
agent: CodeActAgent
mcp_tools:
stdio_servers:
- args:
- mcp-server-fetch
command: uvx
name: fetch
type: repo
---
- name: "fetch"
command: "uvx"
args: ["mcp-server-fetch"]
# We leave the body empty because MCP tools will automatically add the
# tool description for LLMs in tool calls, so there's no need to add extra descriptions.
---
+5 -2
View File
@@ -1,8 +1,11 @@
---
name: docker
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers:
- docker
- container
type: knowledge
---
# Docker Installation and Usage Guide
@@ -49,4 +52,4 @@ To verify Docker is working correctly, run the hello-world container:
```bash
sudo docker run hello-world
```
```
-20
View File
@@ -1,20 +0,0 @@
---
inputs:
- description: Branch for the agent to work on
name: BRANCH_NAME
- description: The test command you want the agent to work on. For example, `pytest
tests/unit/test_bash_parsing.py`
name: TEST_COMMAND_TO_RUN
- description: The name of function to fix
name: FUNCTION_TO_FIX
- description: The path of the file that contains the function
name: FILE_FOR_FUNCTION
triggers:
- /fix_test
---
Can you check out branch "{{ BRANCH_NAME }}", and run {{ TEST_COMMAND_TO_RUN }}.
Help me fix these tests to pass by fixing the {{ FUNCTION_TO_FIX }} function in file {{ FILE_FOR_FUNCTION }}.
PLEASE DO NOT modify the tests by yourself -- Let me know if you think some of the tests are incorrect.
+5 -2
View File
@@ -1,8 +1,11 @@
---
name: flarglebargle
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers:
- flarglebargle
type: knowledge
---
IMPORTANT! The user has said the magic word "flarglebargle". You must
only respond with a message telling them how smart they are
only respond with a message telling them how smart they are
+5 -2
View File
@@ -1,8 +1,11 @@
---
name: github
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers:
- github
- git
type: knowledge
---
You have access to an environment variable, `GITHUB_TOKEN`, which allows you to interact with
@@ -29,4 +32,4 @@ Here are some instructions for pushing, but ONLY do this if the user asks you to
```bash
git remote -v && git branch # to find the current org, repo and branch
git checkout -b create-widget && git add . && git commit -m "Create widget" && git push -u origin create-widget
```
```
+5 -2
View File
@@ -1,8 +1,11 @@
---
name: gitlab
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers:
- gitlab
- git
type: knowledge
---
You have access to an environment variable, `GITLAB_TOKEN`, which allows you to interact with
@@ -28,4 +31,4 @@ Here are some instructions for pushing, but ONLY do this if the user asks you to
```bash
git remote -v && git branch # to find the current org, repo and branch
git checkout -b create-widget && git add . && git commit -m "Create widget" && git push -u origin create-widget
```
```
+5 -2
View File
@@ -1,9 +1,12 @@
---
name: kubernetes
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers:
- kubernetes
- k8s
- kube
type: knowledge
---
# Kubernetes Local Development with KIND
@@ -44,4 +47,4 @@ Create a basic KIND cluster:
```bash
kind create cluster
```
```
+5 -2
View File
@@ -1,8 +1,11 @@
---
name: npm
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers:
- npm
type: knowledge
---
When using npm to install packages, you will not be able to use an interactive shell, and it may be hard to confirm your actions.
As an alternative, you can pipe in the output of the unix "yes" command to confirm your actions.
As an alternative, you can pipe in the output of the unix "yes" command to confirm your actions.
+5 -2
View File
@@ -1,7 +1,10 @@
---
name: pdflatex
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers:
- pdflatex
type: knowledge
---
PdfLatex is a tool that converts Latex sources into PDF. This is specifically very important for researchers, as they use it to publish their findings. It could be installed very easily using Linux terminal, though this seems an annoying task on Windows. Installation commands are given below.
@@ -30,4 +33,4 @@ Once installed as above, you may be able to create PDF files from latex sources
pdflatex latex_source_name.tex
```
Ref: http://kkpradeeban.blogspot.com/2014/04/installing-latexpdflatex-on-ubuntu.html
Ref: http://kkpradeeban.blogspot.com/2014/04/installing-latexpdflatex-on-ubuntu.html
+10 -8
View File
@@ -1,13 +1,15 @@
---
triggers:
- security
- vulnerability
- authentication
- authorization
- permissions
name: security
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers:
- security
- vulnerability
- authentication
- authorization
- permissions
---
This document provides guidance on security best practices
You should always be considering security implications when developing.
@@ -29,4 +31,4 @@ You should always complete the task requested. If there are security concerns pl
- Never expose sensitive information in error messages
- Log security events appropriately
- Implement proper exception handling
- Use secure error reporting mechanisms
- Use secure error reporting mechanisms
+12 -9
View File
@@ -1,13 +1,16 @@
---
triggers:
- ssh
- remote server
- remote machine
- remote host
- remote connection
- secure shell
- ssh keys
name: SSH Microagent
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers:
- ssh
- remote server
- remote machine
- remote host
- remote connection
- secure shell
- ssh keys
---
# SSH Microagent
@@ -131,4 +134,4 @@ chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
# Set correct permissions for SSH directory
chmod 700 ~/.ssh
```
```
+9 -6
View File
@@ -1,9 +1,12 @@
---
triggers:
- swift-linux
- swift-debian
- swift-installation
type: knowledge
name: swift-linux
type: knowledge
agent: CodeActAgent
version: 1.0.0
triggers:
- swift-linux
- swift-debian
- swift-installation
---
# Swift Installation Guide for Debian Linux
@@ -77,4 +80,4 @@ Verify that Swift is correctly installed by running:
```bash
swift --version
```
```
-17
View File
@@ -1,17 +0,0 @@
---
inputs:
- description: URL of the pull request
name: PR_URL
type: string
validation:
pattern: ^https://github.com/.+/.+/pull/[0-9]+$
- description: Branch name corresponds to the pull request
name: BRANCH_NAME
type: string
triggers:
- /update_pr_description
---
Please check the branch "{{ BRANCH_NAME }}" and look at the diff against the main branch. This branch belongs to this PR "{{ PR_URL }}".
Once you understand the purpose of the diff, please use Github API to read the existing PR description, and update it to be more reflective of the changes we've made when necessary.
-16
View File
@@ -1,16 +0,0 @@
---
inputs:
- description: Branch for the agent to work on
name: BRANCH_NAME
- description: The test command you want the agent to work on. For example, `pytest
tests/unit/test_bash_parsing.py`
name: TEST_COMMAND_TO_RUN
triggers:
- /update_test
---
Can you check out branch "{{ BRANCH_NAME }}", and run {{ TEST_COMMAND_TO_RUN }}.
The current implementation of the code is correct BUT the test functions {{ FUNCTION_TO_FIX }} in file {{ FILE_FOR_FUNCTION }} are failing.
Please update the test file so that they pass with the current version of the implementation.
@@ -1,8 +1,5 @@
Please send a final message summarizing your work.
Please summarize your work.
If you simply answered a question, this final message should re-state the answer to the question.
If you made changes, please first double-check the git diff, think carefully about the user's request(s), and check:
1. whether the request has been completely addressed and all of the instructions have been followed faithfully (in checklist format if appropriate).
2. whether the changes are concise (if there are any extraneous changes not important to addressing the user's request they should be reverted).
If the request has been addressed and the changes are concise, then push your changes to the remote branch and send a final message summarizing the changes.
If you answered a question, please re-state the answer to the question
If you made changes, please create a concise overview on whether the request has been addressed successfully or if there are were issues with the attempt.
If successful, make sure your changes are pushed to the remote branch.
+1 -1
View File
@@ -73,7 +73,7 @@ class MCPClient(BaseModel):
)
if conversation_id:
headers['X-OpenHands-ServerConversation-ID'] = conversation_id
headers['X-OpenHands-Conversation-ID'] = conversation_id
# Instantiate custom transports due to custom headers
if isinstance(server, MCPSHTTPServerConfig):
+9 -81
View File
@@ -1,5 +1,4 @@
import io
import re
from pathlib import Path
from typing import Union
@@ -10,7 +9,7 @@ from openhands.core.exceptions import (
MicroagentValidationError,
)
from openhands.core.logger import openhands_logger as logger
from openhands.microagent.types import InputMetadata, MicroagentMetadata, MicroagentType
from openhands.microagent.types import MicroagentMetadata, MicroagentType
class BaseMicroagent(BaseModel):
@@ -92,26 +91,13 @@ class BaseMicroagent(BaseModel):
subclass_map = {
MicroagentType.KNOWLEDGE: KnowledgeMicroagent,
MicroagentType.REPO_KNOWLEDGE: RepoMicroagent,
MicroagentType.TASK: TaskMicroagent,
}
# Infer the agent type:
# 1. If inputs exist -> TASK
# 2. If triggers exist -> KNOWLEDGE
# 3. Else (no triggers) -> REPO (always active)
# 1. If triggers exist -> KNOWLEDGE (optional)
# 2. Else (no triggers) -> REPO (always active)
inferred_type: MicroagentType
if metadata.inputs:
inferred_type = MicroagentType.TASK
# Add a trigger for the agent name if not already present
# Use derived_name if available, otherwise use metadata.name
agent_name = derived_name if derived_name is not None and (metadata.name == 'default' or not metadata.name) else metadata.name
trigger = f'/{agent_name}'
if not metadata.triggers or trigger not in metadata.triggers:
if not metadata.triggers:
metadata.triggers = [trigger]
else:
metadata.triggers.append(trigger)
elif metadata.triggers:
if metadata.triggers:
inferred_type = MicroagentType.KNOWLEDGE
else:
# No triggers, default to REPO
@@ -123,11 +109,7 @@ class BaseMicroagent(BaseModel):
raise ValueError(f'Could not determine microagent type for: {path}')
# Use derived_name if available (from relative path), otherwise fallback to metadata.name
# If metadata.name is still the default 'default', use the derived_name
if derived_name is not None and (metadata.name == 'default' or not metadata.name):
agent_name = derived_name
else:
agent_name = metadata.name
agent_name = derived_name if derived_name is not None else metadata.name
agent_class = subclass_map[inferred_type]
return agent_class(
@@ -140,9 +122,7 @@ class BaseMicroagent(BaseModel):
class KnowledgeMicroagent(BaseMicroagent):
"""Knowledge micro-agents provide specialized expertise that's triggered by keywords in conversations.
They help with:
"""Knowledge micro-agents provide specialized expertise that's triggered by keywords in conversations. They help with:
- Language best practices
- Framework guidelines
- Common patterns
@@ -151,8 +131,8 @@ class KnowledgeMicroagent(BaseMicroagent):
def __init__(self, **data):
super().__init__(**data)
if self.type not in [MicroagentType.KNOWLEDGE, MicroagentType.TASK]:
raise ValueError('KnowledgeMicroagent must have type KNOWLEDGE or TASK')
if self.type != MicroagentType.KNOWLEDGE:
raise ValueError('KnowledgeMicroagent must have type KNOWLEDGE')
def match_trigger(self, message: str) -> str | None:
"""Match a trigger in the message.
@@ -191,57 +171,6 @@ class RepoMicroagent(BaseMicroagent):
)
class TaskMicroagent(KnowledgeMicroagent):
"""TaskMicroagent is a special type of KnowledgeMicroagent that requires user input.
These microagents are triggered by a special format: "/{agent_name}"
and will prompt the user for any required inputs before proceeding.
"""
def __init__(self, **data):
super().__init__(**data)
if self.type != MicroagentType.TASK:
raise ValueError(
f'TaskMicroagent initialized with incorrect type: {self.type}'
)
# Append a prompt to ask for missing variables
self._append_missing_variables_prompt()
def _append_missing_variables_prompt(self) -> None:
"""Append a prompt to ask for missing variables."""
# Check if the content contains any variables or has inputs defined
if not self.requires_user_input() and not self.metadata.inputs:
return
prompt = "\n\nIf the user didn't provide any of these variables, ask the user to provide them first before the agent can proceed with the task."
self.content += prompt
def extract_variables(self, content: str) -> list[str]:
"""Extract variables from the content.
Variables are in the format ${variable_name}.
"""
pattern = r'\$\{([a-zA-Z_][a-zA-Z0-9_]*)\}'
matches = re.findall(pattern, content)
return matches
def requires_user_input(self) -> bool:
"""Check if this microagent requires user input.
Returns True if the content contains variables in the format ${variable_name}.
"""
# Check if the content contains any variables
variables = self.extract_variables(self.content)
logger.debug(f'This microagent requires user input: {variables}')
return len(variables) > 0
@property
def inputs(self) -> list[InputMetadata]:
"""Get the inputs for this microagent."""
return self.metadata.inputs
def load_microagents_from_dir(
microagent_dir: Union[str, Path],
) -> tuple[dict[str, RepoMicroagent], dict[str, KnowledgeMicroagent]]:
@@ -253,7 +182,7 @@ def load_microagents_from_dir(
microagent_dir: Path to the microagents directory (e.g. .openhands/microagents)
Returns:
Tuple of (repo_agents, knowledge_agents) dictionaries
Tuple of (repo_agents, knowledge_agents, task_agents) dictionaries
"""
if isinstance(microagent_dir, str):
microagent_dir = Path(microagent_dir)
@@ -273,7 +202,6 @@ def load_microagents_from_dir(
if isinstance(agent, RepoMicroagent):
repo_agents[agent.name] = agent
elif isinstance(agent, KnowledgeMicroagent):
# Both KnowledgeMicroagent and TaskMicroagent go into knowledge_agents
knowledge_agents[agent.name] = agent
except MicroagentValidationError as e:
# For validation errors, include the original exception
+2 -13
View File
@@ -12,14 +12,6 @@ class MicroagentType(str, Enum):
KNOWLEDGE = 'knowledge' # Optional microagent, triggered by keywords
REPO_KNOWLEDGE = 'repo' # Always active microagent
TASK = 'task' # Special type for task microagents that require user input
class InputMetadata(BaseModel):
"""Metadata for task microagent inputs."""
name: str
description: str
class MicroagentMetadata(BaseModel):
@@ -27,12 +19,9 @@ class MicroagentMetadata(BaseModel):
name: str = 'default'
type: MicroagentType = Field(default=MicroagentType.REPO_KNOWLEDGE)
# Keep these fields for backward compatibility but they're not used
version: str = Field(default='1.0.0', exclude=True)
agent: str = Field(default='CodeActAgent', exclude=True)
author: str = Field(default='', exclude=True)
version: str = Field(default='1.0.0')
agent: str = Field(default='CodeActAgent')
triggers: list[str] = [] # optional, only exists for knowledge microagents
inputs: list[InputMetadata] = [] # optional, only exists for task microagents
mcp_tools: MCPConfig | None = (
None # optional, for microagents that provide additional MCP tools
)
+2 -6
View File
@@ -49,7 +49,7 @@ async def get_convo_link(service: GitService, conversation_id: str, body: str) -
async def save_pr_metadata(
user_id: str | None, conversation_id: str, tool_result: str
user_id: str, conversation_id: str, tool_result: str
) -> None:
conversation_store = await ConversationStoreImpl.get_instance(config, user_id)
conversation: ConversationMetadata = await conversation_store.get_metadata(
@@ -70,11 +70,7 @@ async def save_pr_metadata(
pr_number = int(match_merge_request.group(1))
if pr_number:
logger.info(f'Saving PR number: {pr_number} for convo {conversation_id}')
conversation.pr_number.append(pr_number)
else:
logger.warning(f'Failed to extract PR number for convo {conversation_id}')
await conversation_store.save_metadata(conversation)
@@ -128,7 +124,7 @@ async def create_pr(
body=body,
)
if conversation_id:
if conversation_id and user_id:
await save_pr_metadata(user_id, conversation_id, response)
except Exception as e:
+4 -181
View File
@@ -1,7 +1,6 @@
"""Tests for microagent loading in runtime."""
import os
import tempfile
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock, patch
@@ -14,13 +13,7 @@ from conftest import (
from openhands.core.config import MCPConfig
from openhands.core.config.mcp_config import MCPStdioServerConfig
from openhands.mcp.utils import add_mcp_tools_to_agent
from openhands.microagent.microagent import (
BaseMicroagent,
KnowledgeMicroagent,
RepoMicroagent,
TaskMicroagent,
)
from openhands.microagent.types import MicroagentType
from openhands.microagent import KnowledgeMicroagent, RepoMicroagent
def _create_test_microagents(test_dir: str):
@@ -180,176 +173,6 @@ Repository-specific test instructions.
_close_test_runtime(runtime)
def test_task_microagent_creation():
"""Test that a TaskMicroagent is created correctly."""
content = """---
name: test_task
version: 1.0.0
author: openhands
agent: CodeActAgent
triggers:
- /test_task
inputs:
- name: TEST_VAR
description: "Test variable"
---
This is a test task microagent with a variable: ${test_var}.
"""
with tempfile.NamedTemporaryFile(suffix='.md') as f:
f.write(content.encode())
f.flush()
agent = BaseMicroagent.load(f.name)
assert isinstance(agent, TaskMicroagent)
assert agent.type == MicroagentType.TASK
assert agent.name == 'test_task'
assert '/test_task' in agent.triggers
assert "If the user didn't provide any of these variables" in agent.content
def test_task_microagent_variable_extraction():
"""Test that variables are correctly extracted from the content."""
content = """---
name: test_task
version: 1.0.0
author: openhands
agent: CodeActAgent
triggers:
- /test_task
inputs:
- name: var1
description: "Variable 1"
---
This is a test with variables: ${var1}, ${var2}, and ${var3}.
"""
with tempfile.NamedTemporaryFile(suffix='.md') as f:
f.write(content.encode())
f.flush()
agent = BaseMicroagent.load(f.name)
assert isinstance(agent, TaskMicroagent)
variables = agent.extract_variables(agent.content)
assert set(variables) == {'var1', 'var2', 'var3'}
assert agent.requires_user_input()
def test_knowledge_microagent_no_prompt():
"""Test that a regular KnowledgeMicroagent doesn't get the prompt."""
content = """---
name: test_knowledge
version: 1.0.0
author: openhands
agent: CodeActAgent
triggers:
- test_knowledge
---
This is a test knowledge microagent.
"""
with tempfile.NamedTemporaryFile(suffix='.md') as f:
f.write(content.encode())
f.flush()
agent = BaseMicroagent.load(f.name)
assert isinstance(agent, KnowledgeMicroagent)
assert agent.type == MicroagentType.KNOWLEDGE
assert "If the user didn't provide any of these variables" not in agent.content
def test_task_microagent_trigger_addition():
"""Test that a trigger is added if not present."""
content = """---
name: test_task
version: 1.0.0
author: openhands
agent: CodeActAgent
inputs:
- name: TEST_VAR
description: "Test variable"
---
This is a test task microagent.
"""
with tempfile.NamedTemporaryFile(suffix='.md') as f:
f.write(content.encode())
f.flush()
agent = BaseMicroagent.load(f.name)
assert isinstance(agent, TaskMicroagent)
assert '/test_task' in agent.triggers
def test_task_microagent_no_duplicate_trigger():
"""Test that a trigger is not duplicated if already present."""
content = """---
name: test_task
version: 1.0.0
author: openhands
agent: CodeActAgent
triggers:
- /test_task
- another_trigger
inputs:
- name: TEST_VAR
description: "Test variable"
---
This is a test task microagent.
"""
with tempfile.NamedTemporaryFile(suffix='.md') as f:
f.write(content.encode())
f.flush()
agent = BaseMicroagent.load(f.name)
assert isinstance(agent, TaskMicroagent)
assert agent.triggers.count('/test_task') == 1 # No duplicates
assert len(agent.triggers) == 2
assert 'another_trigger' in agent.triggers
assert '/test_task' in agent.triggers
def test_task_microagent_match_trigger():
"""Test that a task microagent matches its trigger correctly."""
content = """---
name: test_task
version: 1.0.0
author: openhands
agent: CodeActAgent
triggers:
- /test_task
inputs:
- name: TEST_VAR
description: "Test variable"
---
This is a test task microagent.
"""
with tempfile.NamedTemporaryFile(suffix='.md') as f:
f.write(content.encode())
f.flush()
agent = BaseMicroagent.load(f.name)
assert isinstance(agent, TaskMicroagent)
assert agent.match_trigger('/test_task') == '/test_task'
assert agent.match_trigger(' /test_task ') == '/test_task'
assert agent.match_trigger('This contains /test_task') == '/test_task'
assert agent.match_trigger('/other_task') is None
def test_default_tools_microagent_exists():
"""Test that the default-tools microagent exists in the global microagents directory."""
# Get the path to the global microagents directory
@@ -373,9 +196,9 @@ def test_default_tools_microagent_exists():
assert 'type: repo' in content, 'default-tools.md should be a repo microagent'
# Verify it has the fetch tool configured
assert 'name: "fetch"' in content or 'name: fetch' in content, 'default-tools.md should have a fetch tool'
assert 'command: uvx' in content, 'default-tools.md should use uvx command'
assert 'mcp-server-fetch' in content, (
assert 'name: "fetch"' in content, 'default-tools.md should have a fetch tool'
assert 'command: "uvx"' in content, 'default-tools.md should use uvx command'
assert 'args: ["mcp-server-fetch"]' in content, (
'default-tools.md should use mcp-server-fetch'
)
+2 -3
View File
@@ -173,7 +173,7 @@ def test_invalid_microagent_type(temp_microagents_dir):
# Create a microagent with an invalid type
invalid_agent = """---
name: invalid_type_agent
type: invalid_type
type: task
version: 1.0.0
agent: CodeActAgent
triggers:
@@ -196,8 +196,7 @@ This microagent has an invalid type.
# Check that the error message contains helpful information
error_msg = str(excinfo.value)
assert 'invalid_type.md' in error_msg
assert 'Invalid "type" value: "invalid_type"' in error_msg
assert 'Invalid "type" value: "task"' in error_msg
assert 'Valid types are:' in error_msg
assert '"knowledge"' in error_msg
assert '"repo"' in error_msg
assert '"task"' in error_msg