morph-labs / rift

Rift: an AI-native language server for your personal AI software engineer
https://morph.so
Apache License 2.0
3.07k stars 149 forks source link

Feature: Enhance "@" Autocompletions in Chat with Functions and Classes #144

Open cristianoc opened 1 year ago

cristianoc commented 1 year ago

Feature: Enhance "@" Autocompletions in Chat with Functions and Classes

Context

We want to extend the "@" autocompletions in the chat to support functions and classes alongside the current support for files and directories.

Proposal

The Intermediate Representation (IR) can be leveraged to add these autocompletions.

List of Symbols for Autocompletion: A command to provide this list can be built atop the current IR. There are some design considerations:

a. Data Format: How should the list of symbols be represented? For instance, given:

        class Outer1:
            class A:
                def foo(self):
                    pass

        class Outer2:
            class A:
                def foo(self):
                    pass
    A possible JSON format is:
        [
            {"name": "Outer1", "scope": "", "kind": "Class"},
            {"name": "A", "scope": "Outer1.", "kind": "Class"},
            {"name": "foo", "scope": "Outer1.A.", "kind": "Function"},
            {"name": "Outer2", "scope": "", "kind": "Class"},
            {"name": "A", "scope": "Outer2.", "kind": "Class"},
            {"name": "foo", "scope": "Outer2.A.", "kind": "Function"}
        ]

The scope used to be a list of strings in a previous version of the proposal but that would be ambiguous for e.g. C++, where "A::" and "A." are two different valid scopes with different meaning.

b. Client-Side UI: Determine how to show potential completions to users and how to represent (and optionally specify) the scope to disambiguate symbols, e.g., Outer1.A.foo vs Outer2.A.foo.

c. Response Format: Decide how to represent a symbol completion as a URL-like entity alongside what's currently done for files/directories. It should be easily parsed back by the server using a standard parser, and ideally, be interpretable (or even generatable) by an llm.

a/b/c.py#Outer1.A.foo

This parses fine with e.g. urlparse:

>>> urlparse("a/b/c.py#Outer1.A.foo")
ParseResult(scheme='', netloc='', path='a/b/c.py', params='', query='', fragment='Outer1.A.foo')
cristianoc commented 1 year ago

This PR https://github.com/morph-labs/rift/pull/159 adds a command in completions.py to return symbol completions. In addition, the IR is extended with a notion of reference and lookup. References can be expressed as URIs e.g. of this form: