# IDAxLM Developer Notes

## Manual Plugin Setup

### IDAxLM Releases

  To set up a  plugin, download the repository and copy the **idaxlm**   folder to one of the following ***IDA*** plugin directories:

  - Windows
    - *C:\Program Files\IDA \<EDITION\> \<IDA_VERSION\>\plugins*
    - *C:\Users\\<USER_NAME\>\AppData\Roaming\Hex-Rays\IDA Pro\plugins*

  - macOS
    - /Users/\<username\>/.idapro/plugins/

  *If the IDA version earlier than 9.0 is used, as an additional steps do the following:*

  - *change directory to the **idaxlm** folder*
  - *locate the **idaxlm.py** file*
  - *move this file one level up*

### IDAxLM Pre-Releases

To receive continuous updates, clone the repository with ***Git*** and create a *symlink* in the ***IDA*** plugin folder.

- Windows

  - automatically: `install.bat`
  - manually:

  ```shell
  > mklink /d "C:\Program Files\IDA <EDITION> <VERSION>\plugins\idaxlm" <repository_path>\idaxlm
  > mklink "C:\Program Files\IDA <EDITION> <VERSION>\plugins\idaxlm.py" <repository_path>\idaxlm\idaxlm.py (IDA <v9.0)
  ```

- macOS

  - automatically: `install.sh`
  - manually:

  ```shell
  % ln -s <repository_path>/idaxlm /Users/<username>/.idapro/plugins/idaxlm
  % ln -s <repository_path>/idaxlm/idaxlm.py /Users/<username>/.idapro/plugins/idaxlm.py (IDA <v9.0)
  ```

## Providers

While different providers follow their own request schema for interacting with ***LLMs***, it can be said with certainty that each request will involve a combination of **token**, a **model**, and the actual **query** in one form or another.

For any given provider, it cannot be determined in advance whether each component will be part of the **endpoint**, **headers**, or **payload**. However, once the structure is known, the process of prompting is generally the same.

Consider a description of an arbitrary **service** in **IDAxLM**":

```json
"<PROVIDER_NAME>": {
  "endpoint": "<COMMON_COMPLETION_ENDPOINT>",
  "models": {
    "<MODEL_1>": {
      // <OPTIONAL_PRICING_DATA_1>
    },
    ...
    "<MODEL_N>": {
      // <OPTIONAL_PRICING_DATA_N>
    }
  },
  "headers": {
    // <OPTIONAL_HEADERS_DATA>
  },
  "payload": {
    // <OPTIONAL_PAYLOAD_DATA>
  }
}
```

The corresponding `<token>`, `<model>`, `<query>` placeholder tags should be placed in this structure where needed. They will be replaced with actual values during prompting:

- the right provider and model will be picked based on the user's choice in the **Provider Tool**;
- the corresponding token will be retrieved from the `.env` file;
- the query will be constructed using data from the Context and Prompt tabs.

Adding a new service is straightforward — it requires to add a new structure to the `<plugin_path>/data/config.json` file.

There are official pip packages that work with models from specific providers; however, using them would introduce additional dependencies and vendor-specific code. ***IDAxLM*** will adhere to the defined heuristic where applicable.

## Extensions

The plugin comes with a set of predefined ***templates*** and ***mappers***.  

Template configurations are located in these files:

- `./data/context.json`
- `./data/prompt.json`
- `./data/linker.json`

The following files contain the mapper definitions:

- `./data/picker.py`
- `./data/mutant.py`
- `./data/linker.py`

These files should also be modified if there is a need to extend the standard plugin behavior. The required structure for templates and mappers is outlined below.

### Template Structure

Extending templates involves adding new text content while maintatining existing naming conventions for *JSON* descriptors.

- picker template

  ```json
  "algorithm": {
    "picker": "get_<PICKER_NAME>",
    "handle": "text",
    "default": "<DEFAULT_VALUE>",
    "mutant": "fix_<MUTANT_NAME>",
    "prompt": "<PROMPT_TEMPLATE_STRING>"
  }
  ```

- prompt template

  ```json
  "var_names": {
    "text": "<QUESTION/COMMAND>",
    "type": "<OUTPUT_TEXT_FORMAT>",
    "case": "<INPUT_OUTPUT_EXAMPLE>",
    "safe": "<CONSISTENCY_DIRECTIVES>",
    "link": ["set_<LINKER_NAME_1>", "set_<LINKER_NAME_2>", "set_<LINKER_NAME_N>"]
  }
  ```

- linker template

  ```json
  {
    ...
    "set_<LINKER_NAME>": "<LINKER_MENU_TEXT>",
    ...
  }
  ```

### Mapper Structure

Extending mappers involves writing *Python* code while adhering to function naming conventions (`get_`, `fix_`, `set_`) and maintaining argument lists.

- picker mapper

  ```python
  def get_<PICKER_NAME>(func_ea, plug_env):
      # <picker logic>
      return tmpl_val
  ```

- mutant mapper

  ```python
  def fix_<MUTANT_NAME>(tmpl_val, plug_env):
      # <mutant logic>
      return tmpl_fix
  ```

- linker mapper

  ```python
  def set_<LINKER_NAME>(func_ea, llm_val, llm_name, plug_env):
      # <linker logic>
      update_ui(func_ea)
  ```
