HyperAgent

repository·main·Indexed 42 days ago

https://github.com/fsoft-ai4code/hyperagent

A multi-agent coding assistant for codebase exploration and analysis, version 0.0.1. It utilizes a specialized architecture of four agents—Planner, Navigator, Code Editor, and Executor—to handle software engineering tasks such as GitHub issue resolution, code generation, and fault localization. HyperAgent includes a Python API, a CLI for repository indexing and querying, and a VS Code extension for integrated AI-driven code explanation, refactoring, and optimization.

Tokens
21.8K
Snippets
57
Records
101
Agent score
54%

What's inside HyperAgent

  1. Understand the extension structure and API

    main

    The extension is composed of the following key files:

    • package.json: The manifest file where you declare extension commands, titles, and command names. This allows VS Code to register commands in the command palette.
    • src/extension.ts: The main entry point. It exports an activate function called when the extension is triggered. Inside activate, you use registerCommand to bind implementation logic to a command.
    • node_modules/@types/vscode/index.d.ts: The location of the full VS Code API definitions for reference.

    Implementation Pattern: Commands are registered by passing the implementation function as the second parameter to registerCommand within the activate function.

    // Inside src/extension.ts
    export function activate(context: vscode.ExtensionContext) {
        let disposable = vscode.commands.registerCommand('extension.helloWorld', () => {
            // Command implementation
        });
    
        context.subscriptions.push(disposable);
    }
  2. How to implement a custom task in HyperAgent

    main

    To solve new tasks or perform systematic evaluations, create a new task class and implement the run method. The run method must return the result of the task (e.g., a patch or a prediction).

    # Example implementation pattern
    def run(self, system, idx) -> Result:
          prompt = self.construct_prompt(idx)
          system.query_codebase(prompt)
          prediction_patch = extract_patch(system.repo_dir)
          return prediction_patch
  3. Install Zoekt and universal-ctags for code search

    main

    HyperAgent requires Zoekt for code search and universal-ctags for semantic code search.

    1. Install Zoekt: Requires Go. Install the indexer and web server using:
      go get github.com/sourcegraph/zoekt/
      go install github.com/sourcegraph/zoekt/cmd/zoekt-index
      go install github.com/sourcegraph/zoekt/cmd/zoekt-webserver
    2. Install universal-ctags: Follow the official instructions.
    3. Configure Environment: Set the CTAGS_COMMAND environment variable to universal-ctags.
    go get github.com/sourcegraph/zoekt/
    # Install Zoekt Index
    go install github.com/sourcegraph/zoekt/cmd/zoekt-index
    # Install Zoekt Web Server
    go install github.com/sourcegraph/zoekt/cmd/zoekt-webserver
    
    # Set environment variable
    export CTAGS_COMMAND=universal-ctags
  4. Reproduce evaluation results for SWE-Bench and Defects4J

    main

    Scripts to reproduce the benchmark results provided in the paper are located in the scripts folder.

    SWE-Bench:

    python3 scripts/run_swe_bench.py --split "test"

    Defects4J Fault Localization:

    python3 scripts/run_defects4j_fl.py

    Defects4J Program Repair:

    python3 scripts/run_defects4j_apr.py
  5. Install HyperAgent

    main

    It is mandatory to create a new conda environment named hyperagent before installation because the Executor agent uses a Jupyter kernel named hyperagent to execute code.

    conda create -n hyperagent python=3.10
    pip3 install -e .
    conda create -n hyperagent python=3.10
    pip3 install -e .
  6. Run extension tests

    main

    To execute the test suite:

    1. Open the Debug Viewlet (Ctrl+Shift+D or Cmd+Shift+D on Mac).
    2. Select Extension Tests from the launch configuration dropdown.
    3. Press F5 to run the tests in a new window.
    4. Check the Debug Console for test results.

    Test Configuration:

    • Test files must match the pattern **.test.ts.
    • You can add new tests by creating files inside the test/suite folder.
    F5
  7. Run and debug the VS Code extension

    main

    You can launch the extension in a new window for testing and debugging using these steps:

    1. Launch: Press F5 to open a new window with your extension loaded.
    2. Execute Command: Open the command palette (Ctrl+Shift+P or Cmd+Shift+P on Mac) and type the command name (e.g., Hello World) to trigger the extension logic.
    3. Debug: Set breakpoints directly in src/extension.ts. View extension output in the Debug Console.
    4. Relaunch: After making changes to src/extension.ts, you can either use the debug toolbar to relaunch or reload the VS Code window (Ctrl+R or Cmd+R on Mac) to apply changes.
    F5
  8. Use Type Hierarchy features

    main

    Type hierarchy allows navigating through supertypes and subtypes of a type (introduced in LSP 3.17.0).

    • Preparation: Use textDocument/prepareTypeHierarchy with TypeHierarchyPrepareParams to identify the starting point in a document.
    • Navigation:
      • typeHierarchy/supertypes: Uses TypeHierarchySupertypesParams to find parent types.
      • typeHierarchy/subtypes: Uses TypeHierarchySubtypesParams to find child types.
    • TypeHierarchyItem: Represents a node in the hierarchy, containing metadata like name, kind, uri, and range similar to a standard symbol.
  9. Configure Inlay Hints

    main

    Inlay hints provide additional information (like parameter names or inferred types) directly in the editor.

    • Requesting Hints: Use InlayHintParams specifying the textDocument and the range to compute hints for.
    • InlayHint Structure: An InlayHint includes a position, a label (string or InlayHintLabelPart), and an optional kind. It can also include textEdits that are performed when the hint is accepted, and a tooltip for hover information.
    • Registration: InlayHintRegistrationOptions allows the server to indicate if it provides a resolveProvider for additional information.
  10. Configure HyperAgent agents and modes

    main

    HyperAgent supports two modes via the config dictionary:

    • patch: The agent generates a patch for a given task.
    • predict: The agent predicts the next token (used for tasks like repoQA or fault localization).

    The configuration allows specifying different LLM models, API keys, and parameters for each of the four specialized agents: plan, nav, edit, and exec.

    config = {
            "name": "claude",
            "nav": [{
                "model": "claude-3-haiku-20240307",
                "api_key": os.environ.get("ANTHROPIC_API_KEY"),
                "stop_sequences": ["\nObservation:"],
                "base_url": "https://api.anthropic.com",
                "api_type": "anthropic",
            }],
            "edit": [{
                "model": "claude-3-5-sonnet-20240620",
                "api_key": os.environ.get("ANTHROPIC_API_KEY"),
                "stop_sequences": ["\nObservation:"],
                "price": [0.003, 0.015],
                "base_url": "https://api.anthropic.com",
                "api_type": "anthropic",
            }],
            "exec": [{
                "model": "claude-3-5-sonnet-20240620",
                "api_type": os.environ.get("ANTHROPIC_API_KEY"),
                "stop_sequences": ["\nObservation:"],
                "price": [0.003, 0.015],
                "base_url": "https://api.anthropic.com",
                "api_type": "anthropic",
            }],
            "plan": [{
                "model": "claude-3-5-sonnet-20240620",
                "api_type": os.environ.get("ANTHROPIC_API_KEY"),
                "price": [0.003, 0.015],
                "base_url": "https://api.anthropic.com",
                "api_type": "anthropic",
            }],
            "type": "patch"
        }
  11. Handle Call Hierarchy requests and results

    main

    The LSP protocol supports call hierarchy features to navigate between callers and callees.

    • Registration: Use CallHierarchyRegistrationOptions to register for call hierarchy requests, optionally specifying a documentSelector and an id for deregistration.
    • Incoming Calls: The callHierarchy/incomingCalls request uses CallHierarchyIncomingCallsParams, which requires a CallHierarchyItem. The response contains CallHierarchyIncomingCall objects, which include the caller (from) and the ranges where the calls occur (fromRanges).
    • Outgoing Calls: The callHierarchy/outgoingCalls request uses CallHierarchyOutgoingCallsParams. The response contains CallHierarchyOutgoingCall objects, which include the callee (to) and the ranges where the item is called (fromRanges).
    • Call Hierarchy Item: A CallHierarchyItem represents a symbol and includes its name, kind, uri, range (enclosing the symbol), and selectionRange (the specific part of the symbol to reveal, like a function name).
    class CallHierarchyItem(TypedDict):
        name: str
        kind: "SymbolKind"
        tags: NotRequired[List["SymbolTag"]]
        detail: NotRequired[str]
        uri: "DocumentUri"
        range: "Range"
        selectionRange: "Range"
        data: NotRequired["LSPAny"]