Commit graph

169 commits

Author SHA1 Message Date
Paul Gauthier
360335f624 small repo map 2023-06-02 13:09:52 -07:00
Paul Gauthier
ac21a4a992 wip 2023-06-02 12:54:06 -07:00
Paul Gauthier
777a36d366 aider: Modified get_ranked_tags_map to use binary search.
# Context:
USER: make `get_ranked_tags_map` use binary search
ASSISTANT: To modify the `get_ranked_tags_map` function to use binary search, follow these steps:

1. Replace the for loop with a binary search implementation.
2. Update the loop to calculate the middle index and generate the tree with the middle index.
3. Check if the number of tokens is less than `max_map_tokens`. If it is, update the lower bound. Otherwise, update the upper bound.
4. Continue the binary search until the lower bound is greater than or equal to the upper bound.

Here's the updated `get_ranked_tags_map` function:

```python
aider/repomap.py
<<<<<<< ORIGINAL
    def get_ranked_tags_map(self, fnames):
        # 1/4 of gpt-4's context window
        max_map_tokens = 2048

        ranked_tags = self.get_ranked_tags(fnames)
        num_tags = len(ranked_tags)

        for i in range(num_tags, 0, -1):
            tree = to_tree(ranked_tags[:i])
            num_tokens = self.token_count(tree)
            dump(i, num_tokens)
            if num_tokens < max_map_tokens:
                return tree
=======
    def get_ranked_tags_map(self, fnames):
        # 1/4 of gpt-4's context window
        max_map_tokens = 2048

        ranked_tags = self.get_ranked_tags(fnames)
        num_tags = len(ranked_tags)

        lower_bound = 0
        upper_bound = num_tags
        best_tree = None

        while lower_bound <= upper_bound:
            middle = (lower_bound + upper_bound) // 2
            tree = to_tree(ranked_tags[:middle])
            num_tokens = self.token_count(tree)

            if num_tokens < max_map_tokens:
                best_tree = tree
                lower_bound = middle + 1
            else:
                upper_bound = middle - 1

        return best_tree
>>>>>>> UPDATED
```
2023-06-02 12:46:03 -07:00
Paul Gauthier
1bbe8e63af find the best tags map that fits in max_tokens 2023-06-02 12:44:46 -07:00
Paul Gauthier
f92249a7ea refac 2023-06-02 12:40:40 -07:00
Paul Gauthier
e3aed997bc ranked_tags 2023-06-02 12:34:28 -07:00
Paul Gauthier
6e51675072 graph 2023-06-02 11:25:10 -07:00
Paul Gauthier
903d318a8a no weights 2023-06-02 10:55:43 -07:00
Paul Gauthier
746f4ccb56 rank flows evenly *out* from a node 2023-06-01 14:58:15 -07:00
Paul Gauthier
33f649dbbd noop 2023-06-01 14:54:04 -07:00
Paul Gauthier
594c4b600b cleanup 2023-06-01 13:24:52 -07:00
Paul Gauthier
bb0d58020c use in-edges 2023-06-01 13:12:15 -07:00
Paul Gauthier
915a9132de working ranked defs 2023-06-01 11:26:49 -07:00
Paul Gauthier
27566353a6 ssh 2023-06-01 10:57:48 -07:00
Paul Gauthier
11a7f9a80a aider: Calculated the sum of the weights of every inbound edge to each node and stored the result in the inbound_weights dictionary.
# Context:
USER: do the todo
ASSISTANT: I see a "todo" comment in the `aider/repomap.py` file. To complete the task, we need to calculate the sum of the weights of every inbound edge to each node in the graph. Here's how to do it:

```python
aider/repomap.py
<<<<<<< ORIGINAL
    for node in G.nodes:
        # todo: sum up the weight of every inbound edge to node
        pass
=======
    inbound_weights = {}
    for node in G.nodes:
        inbound_weights[node] = sum(data["weight"] for _, _, data in G.in_edges(node, data=True))
>>>>>>> UPDATED
```

This code calculates the sum of the weights of every inbound edge to each node and stores the result in the `inbound_weights` dictionary.
2023-06-01 10:56:41 -07:00
Paul Gauthier
d913d08f39 Merge branch 'main' into call-graph 2023-06-01 10:55:49 -07:00
Paul Gauthier
d1f05ca18a Handle io=none 2023-06-01 10:55:39 -07:00
Paul Gauthier
1aa8c3983d wip 2023-06-01 10:54:43 -07:00
Paul Gauthier
3c9991b38f Merge branch 'main' into call-graph 2023-06-01 09:07:26 -07:00
Paul Gauthier
7bc26e6762 Added --verbose support to repomap 2023-06-01 09:04:08 -07:00
Paul Gauthier
6567577855 works 2023-06-01 07:16:47 -07:00
Paul Gauthier
800ad12ae4 wip 2023-06-01 06:48:39 -07:00
Paul Gauthier
c46e8daa32 use networkx exclusively to maintain the graph structure 2023-05-31 16:53:42 -07:00
Paul Gauthier
b88dc7828c noop 2023-05-31 16:43:52 -07:00
Paul Gauthier
a553d71ca2 noop 2023-05-31 15:34:17 -07:00
Paul Gauthier
c635217d6a wip 2023-05-31 05:58:56 -07:00
Paul Gauthier
a216754c9f noqa 2023-05-30 17:07:12 -07:00
Paul Gauthier
4297e75b9b fixed up shelve 2023-05-30 17:06:02 -07:00
Paul Gauthier
a9b53569ac aider: Switched both caches to use shelve instead of json.
# Context:
USER: switch both caches to use shelve instead of json
ASSISTANT: To switch both caches to use `shelve` instead of `json`, we need to modify the `aider/repomap.py` file. We will update the `load_tags_cache`, `save_tags_cache`, `load_ident_cache`, and `save_ident_cache` methods.

Here are the changes:

```python
aider/repomap.py
<<<<<<< ORIGINAL
import json
=======
import shelve
>>>>>>> UPDATED
```

```python
aider/repomap.py
<<<<<<< ORIGINAL
    IDENT_CACHE_FILE = ".aider.ident.cache.json"
    TAGS_CACHE_FILE = ".aider.tags.cache.json"

    def load_tags_cache(self):
        if os.path.exists(self.TAGS_CACHE_FILE):
            with open(self.TAGS_CACHE_FILE, "r") as f:
                self.TAGS_CACHE = json.load(f)
        else:
            self.TAGS_CACHE = dict()

    def save_tags_cache(self):
        with open(self.TAGS_CACHE_FILE, "w") as f:
            json.dump(self.TAGS_CACHE, f)
=======
    IDENT_CACHE_FILE = ".aider.ident.cache"
    TAGS_CACHE_FILE = ".aider.tags.cache"

    def load_tags_cache(self):
        if os.path.exists(self.TAGS_CACHE_FILE):
            with shelve.open(self.TAGS_CACHE_FILE) as db:
                self.TAGS_CACHE = dict(db)
        else:
            self.TAGS_CACHE = dict()

    def save_tags_cache(self):
        with shelve.open(self.TAGS_CACHE_FILE) as db:
            db.update(self.TAGS_CACHE)
>>>>>>> UPDATED
```

```python
aider/repomap.py
<<<<<<< ORIGINAL
    def load_ident_cache(self):
        if os.path.exists(self.IDENT_CACHE_FILE):
            with open(self.IDENT_CACHE_FILE, "r") as f:
                self.IDENT_CACHE = json.load(f)
        else:
            self.IDENT_CACHE = dict()

    def save_ident_cache(self):
        with open(self.IDENT_CACHE_FILE, "w") as f:
            json.dump(self.IDENT_CACHE, f)
=======
    def load_ident_cache(self):
        if os.path.exists(self.IDENT_CACHE_FILE):
            with shelve.open(self.IDENT_CACHE_FILE) as db:
                self.IDENT_CACHE = dict(db)
        else:
            self.IDENT_CACHE = dict()

    def save_ident_cache(self):
        with shelve.open(self.IDENT_CACHE_FILE) as db:
            db.update(self.IDENT_CACHE)
>>>>>>> UPDATED
```

These changes will replace the usage of `json` with `shelve` for both caches.
2023-05-30 17:03:31 -07:00
Paul Gauthier
bd57c71898 fix up json cache 2023-05-30 17:01:30 -07:00
Paul Gauthier
d1bbb85437 aider: Added methods to load and save tags cache to .aider.tags.cache file.
# Context:
USER: persist the tags cache to .aider.tags.cache
ASSISTANT: To persist the tags cache to `.aider.tags.cache`, you need to modify the `aider/repomap.py` file. Add two new methods `load_tags_cache` and `save_tags_cache` to the `RepoMap` class, and call them in the `__init__` method and `run_ctags` method, respectively.

Here are the changes you need to make:

```python
aider/repomap.py
<<<<<<< ORIGINAL
    TAGS_CACHE_FILE = ".aider.tags.cache"
=======
    TAGS_CACHE_FILE = ".aider.tags.cache"

    def load_tags_cache(self):
        if os.path.exists(self.TAGS_CACHE_FILE):
            with open(self.TAGS_CACHE_FILE, "r") as f:
                self.TAGS_CACHE = json.load(f)
        else:
            self.TAGS_CACHE = dict()

    def save_tags_cache(self):
        with open(self.TAGS_CACHE_FILE, "w") as f:
            json.dump(self.TAGS_CACHE, f)
>>>>>>> UPDATED
```

```python
aider/repomap.py
<<<<<<< ORIGINAL
    def __init__(self, use_ctags=None, root=None, main_model="gpt-4"):
=======
    def __init__(self, use_ctags=None, root=None, main_model="gpt-4"):
        self.load_tags_cache()
>>>>>>> UPDATED
```

```python
aider/repomap.py
<<<<<<< ORIGINAL
    def run_ctags(self, filename):
        # Check if the file is in the cache and if the modification time has not changed
        file_mtime = os.path.getmtime(filename)
        cache_key = filename
        if cache_key in self.TAGS_CACHE and self.TAGS_CACHE[cache_key]["mtime"] == file_mtime:
            return self.TAGS_CACHE[cache_key]["data"]

        cmd = self.ctags_cmd + [filename]
        output = subprocess.check_output(cmd).decode("utf-8")
        output = output.splitlines()

        data = [json.loads(line) for line in output]

        # Update the cache
        self.TAGS_CACHE[cache_key] = {"mtime": file_mtime, "data": data}
=======
    def run_ctags(self, filename):
        # Check if the file is in the cache and if the modification time has not changed
        file_mtime = os.path.getmtime(filename)
        cache_key = filename
        if cache_key in self.TAGS_CACHE and self.TAGS_CACHE[cache_key]["mtime"] == file_mtime:
            return self.TAGS_CACHE[cache_key]["data"]

        cmd = self.ctags_cmd + [filename]
        output = subprocess.check_output(cmd).decode("utf-8")
        output = output.splitlines()

        data = [json.loads(line) for line in output]

        # Update the cache
        self.TAGS_CACHE[cache_key] = {"mtime": file_mtime, "data": data}
        self.save_tags_cache()
>>>>>>> UPDATED
```

These changes will load the tags cache from the `.aider.tags.cache` file when initializing the `RepoMap` class and save the updated cache to the file after running ctags.
2023-05-30 16:54:36 -07:00
Paul Gauthier
29ca124f5f Fixed persisting ident cache 2023-05-30 16:52:28 -07:00
Paul Gauthier
311fc1d6e1 aider: Persist the IDENT_CACHE to .aider.ident.cache whenever it is updated.
# Context:
USER: persist the `IDENT_CACHE` to .aider.ident.cache whenever it is updated
ASSISTANT: To persist the `IDENT_CACHE` to `.aider.ident.cache` whenever it is updated, we need to modify the `get_name_identifiers` method in the `RepoMap` class. Here are the changes:

```python
aider/repomap.py
<<<<<<< ORIGINAL
    def get_name_identifiers(self, fname, uniq=True):
        file_mtime = os.path.getmtime(fname)
        cache_key = fname
        if cache_key in self.IDENT_CACHE and self.IDENT_CACHE[cache_key]["mtime"] == file_mtime:
            idents = self.IDENT_CACHE[cache_key]["data"]
        else:
            idents = self.get_name_identifiers_uncached(fname)
            self.IDENT_CACHE[cache_key] = {"mtime": file_mtime, "data": idents}
=======
import json

class RepoMap:
    # ...
    IDENT_CACHE_FILE = ".aider.ident.cache"

    def __init__(self, use_ctags=None, root=None, main_model="gpt-4"):
        # ...
        self.load_ident_cache()

    def load_ident_cache(self):
        if os.path.exists(self.IDENT_CACHE_FILE):
            with open(self.IDENT_CACHE_FILE, "r") as f:
                self.IDENT_CACHE = json.load(f)
        else:
            self.IDENT_CACHE = dict()

    def save_ident_cache(self):
        with open(self.IDENT_CACHE_FILE, "w") as f:
            json.dump(self.IDENT_CACHE, f)

    def get_name_identifiers(self, fname, uniq=True):
        file_mtime = os.path.getmtime(fname)
        cache_key = fname
        if cache_key in self.IDENT_CACHE and self.IDENT_CACHE[cache_key]["mtime"] == file_mtime:
            idents = self.IDENT_CACHE[cache_key]["data"]
        else:
            idents = self.get_name_identifiers_uncached(fname)
            self.IDENT_CACHE[cache_key] = {"mtime": file_mtime, "data": idents}
            self.save_ident_cache()
>>>>>>> UPDATED
```

This will load the `IDENT_CACHE` from the `.aider.ident.cache` file when the `RepoMap` class is initialized and save the cache to the file whenever it is updated.
2023-05-30 16:50:56 -07:00
Paul Gauthier
49374d04b5 aider: Made IDENT_CACHE use mtime like TAGS_CACHE.
# Context:
USER: make `IDENT_CACHE` use mtime like `TAGS_CACHE`
ASSISTANT: To make `IDENT_CACHE` use mtime like `TAGS_CACHE`, we need to modify the `get_name_identifiers` and `get_name_identifiers_uncached` methods in the `RepoMap` class. Here are the changes:

```python
aider/repomap.py
<<<<<<< ORIGINAL
    def get_name_identifiers(self, fname, uniq=True):
        idents = self.IDENT_CACHE.get(fname)
        if idents is None:
            idents = self.get_name_identifiers_uncached(fname)
            self.IDENT_CACHE[fname] = idents
=======
    def get_name_identifiers(self, fname, uniq=True):
        file_mtime = os.path.getmtime(fname)
        cache_key = fname
        if cache_key in self.IDENT_CACHE and self.IDENT_CACHE[cache_key]["mtime"] == file_mtime:
            idents = self.IDENT_CACHE[cache_key]["data"]
        else:
            idents = self.get_name_identifiers_uncached(fname)
            self.IDENT_CACHE[cache_key] = {"mtime": file_mtime, "data": idents}
>>>>>>> UPDATED

```
2023-05-30 16:49:12 -07:00
Paul Gauthier
a7ca584859 refac 2023-05-30 16:47:50 -07:00
Paul Gauthier
4a1e252bfc noop 2023-05-30 14:25:55 -07:00
Paul Gauthier
313968415a wip 2023-05-30 14:15:29 -07:00
Paul Gauthier
2353e54628 moved get_name_identifiers 2023-05-30 14:07:05 -07:00
Paul Gauthier
497b04acd3 Merge branch 'main' into call-graph 2023-05-30 13:57:16 -07:00
Paul Gauthier
77d20b6819 Fixed TAGS_CACHE 2023-05-30 13:54:56 -07:00
Paul Gauthier
5801bd9ca4 aider: Moved TAGS_CACHE into the RepoMap class.
# Context:
USER: move `TAGS_CACHE` into the class
ASSISTANT: To move the `TAGS_CACHE` into the `RepoMap` class, I will make the following changes:

```python
aider/repomap.py
<<<<<<< ORIGINAL
# Global cache for tags
TAGS_CACHE = {}
=======
>>>>>>> UPDATED
```

```python
aider/repomap.py
<<<<<<< ORIGINAL
class RepoMap:
    ctags_cmd = ["ctags", "--fields=+S", "--extras=-F", "--output-format=json"]

    def __init__(self, use_ctags=None, root=None, main_model="gpt-4"):
=======
    class RepoMap:
        ctags_cmd = ["ctags", "--fields=+S", "--extras=-F", "--output-format=json"]
        TAGS_CACHE = {}

        def __init__(self, use_ctags=None, root=None, main_model="gpt-4"):
>>>>>>> UPDATED
```

Now, the `TAGS_CACHE` is a class attribute of the `RepoMap` class.
2023-05-30 13:53:31 -07:00
Paul Gauthier
27bd993cab Merge branch 'main' into call-graph 2023-05-29 11:18:30 -07:00
Paul Gauthier
92cd2f3ce6 isort 2023-05-28 22:47:38 -07:00
Paul Gauthier
f6197fac40 cleanup 2023-05-28 22:29:21 -07:00
Paul Gauthier
346eb7a834 aider: Replaced string with bytes object in test_check_for_ctags_success to fix 'decode' method issue.
# Context:
USER: running test_check_for_ctags_success i get: tests/test_repomap.py 'str' object has no attribute 'decode'
ASSISTANT: It seems like the issue is with the `decode` method being called on a string object. I'll fix this issue for you. Here's the change you need to make in the `tests/test_repomap.py` file:

```python
tests/test_repomap.py
<<<<<<< ORIGINAL
            mock_run.return_value = CompletedProcess(args=["ctags", "--version"], returncode=0, stdout='''{
  "_type": "tag",
  "name": "status",
  "path": "aider/main.py",
  "pattern": "/^    status = main()$/",
  "kind": "variable"
}''')
=======
            mock_run.return_value = CompletedProcess(args=["ctags", "--version"], returncode=0, stdout=b'''{
  "_type": "tag",
  "name": "status",
  "path": "aider/main.py",
  "pattern": "/^    status = main()$/",
  "kind": "variable"
}''')
>>>>>>> UPDATED
```

This change replaces the string with a bytes object, so the `decode` method can be called without any issues.
2023-05-28 22:18:18 -07:00
Paul Gauthier
065388eb0f wip 2023-05-27 04:34:12 -07:00
Paul Gauthier
316c11465b aider: Added fontcolor to dot.edge label.
# Context:
USER: set the dot.edge label color to color
ASSISTANT: ```python
aider/repomap.py
<<<<<<< ORIGINAL
        dot.edge(refs, defs, penwidth=str(weight), color=color, label=label)
=======
        dot.edge(refs, defs, penwidth=str(weight), color=color, label=label, fontcolor=color)
>>>>>>> UPDATED
```
2023-05-26 18:53:18 -07:00
Paul Gauthier
0ab7d0c1f1 wip 2023-05-26 18:52:41 -07:00
Paul Gauthier
2a28c9453c aider: Added fontsize attribute to dot.node function call in call_map() function in aider/repomap.py to make the font size of the node label scale with the size of the node.
# Context:
USER: make the dot.node font scale with size
ASSISTANT: To make the font scale with the size of the node, we need to modify the `dot.node` function call in the `call_map()` function in the `aider/repomap.py` file. We will add the `fontsize` attribute and set it proportional to the `size`.

Here's the change:

```python
aider/repomap.py
<<<<<<< ORIGINAL
        dot.node(fname, penwidth=str(pen), width=str(size), height=str(size))
=======
        fontsize = str(10 * size)
        dot.node(fname, penwidth=str(pen), width=str(size), height=str(size), fontsize=fontsize)
>>>>>>> UPDATED
```

This will make the font size of the node label scale with the size of the node.
2023-05-26 18:44:31 -07:00
Paul Gauthier
dc1c3e467d Changed graphviz.Graph() to graphviz.Digraph() with a graph_attr ratio of .5. 2023-05-26 18:43:46 -07:00