-
-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Design proposal: Chat Completions API (rev. 0) #143
Comments
cc @michaelchia |
@mlucool shared some feedback about this to me privately. To summarize Marc's feedback: the completers should live in the frontend, and This proposed revision brings several benefits:
In summary, this change would strictly decrease the number of network calls made, and strictly increase the scope of server APIs available to each completer. This seems quite reasonable, so I will work on a new revision of this design and open it as a separate issue. |
While that is true, my main point is to design it in a way that puts the UX, which includes giving the front end ways to improve rending performance. In part, because the server may be blocked at any point in time by something else happening. Moving this also lets you have control over the UX of the completer. I think a file completer would want a different experience than an variable one. As an example, for the The |
@mlucool Thanks for clarifying! Apologies for missing those details. I've added your feedback in the next revision of this design. |
Description
This issue proposes a design for a new Chat Completions API. This API will allow consumer extensions to provide completions for the user's current input from the UI. In this context, a consumer extension is any frontend + server extension that intends to provide completions for substrings in the chat input.
Motivation
Suppose a user types
/
in the chat with Jupyter AI installed. Today, Jupyter Chat responds by showing a menu of chat completions:The opening of this completions menu is triggered simply by typing
/
. However, because the current API only allows a single "trigger character", this doesn't work when@
is typed, meaning that@file
commands cannot be auto-completed.This design aims to:
To help explain the proposed design, this document will start from the perspective of a consumer extension, then work backwards towards the necessary changes in Jupyter Chat.
Step 1: Defining & providing a
ChatCompleter
To register completions for partial inputs, a consumer extension must provide a set of chat completers. A chat completer is a Python class which provides:
id
(property): Defines a unique ID for this chat completer. We will see why this is useful later.regex
(property): Defines a regex which matches any incomplete input.$
to ensure this regex only matches partial inputs just typed by the user. Without$
, the completer may generate completions for commands which were already typed.get_completions(match: str) -> List[ChatCompletion]
Defines a method which accepts a substring matched by its regex, and returns a list of potential completions for that input. This list may be empty.ChatCompletion
will be defined later; for now, we can think of this method as just returning a list of strings that are potential completions to the user's input.Jupyter Chat will provide an
AbstractChatCompleter
class that defines the structure of the chat completer class, shown below.To define a chat completer, a consumer extension should implement the
AbstractChatCompleter
class. Here is an example of how Jupyter AI may implement a chat completer to provide completions for its slash commands:Finally, for a consumer extension to provide these chat completers to Jupyter Chat, the consumer extension must declare each class as an entry point in a fixed entry point group. When Jupyter Chat reads from this entry point group on init, Jupyter Chat can gather all chat completer classes from every consumer extension.
Entry points are defined in PyPA entry points specification. Entry points are used already in Jupyter AI to allow other extensions to add extra chat commands. We will not go into detail here, as Jupyter AI already serves as an implementation reference.
Step 2: Define the chat completion REST API
From the example
SlashCommandCompleter
implementation above, we can piece together what Jupyter Chat's frontend should do:The frontend implementation should debounce how frequently it checks the input for step 2, since it will be expensive to do on every typed character.
To make this possible, we need to define a new REST API for chat completion.
Completions REST API
GET /chat/completers
: Returns aChatCompletersResponse
object, which describes all of the chat completers provided to Jupyter Chat by consumer extensions.POST /chat/completion_matches
: Returns aChatCompletionsResponse
object given aChatCompletionsRequest
object in the request body. This fetches the list of completions from any input. This should be triggered when the user's chat input matches any of the regexes fromGET /chat/completers
.Request & response types
Example request flow
In this section, we will explore the REST API calls made in an example setting. This assumes that this design has been implemented exactly as stated, and that
SlashCommandCompleter
has been provided by another consumer extension.When a user opens JupyterLab, the frontend immediately calls
GET /chat/completers
to fetch the list of completers & their regexes. With just one completer provided, theChatCompletersResponse
object is:Then, the user types
/h
. This matches the regex ofSlashCommandCompleter
, so the frontend callsPOST /chat/completion_matches
with aChatCompletionsRequest
object:The backend receives this request and responds with a
ChatCompletionsResponse
object. Here, we assume that/help
is the only valid completion.The user's menu now has a single completion for
/h
, which replaces/h
with/help
when accepted.Conclusion
Together, the entry points API (step 1) and the REST API (step 2) form the proposed Chat Completion API.
Benefits & applications
id
, so two completers can use the same regex but yield two different sets of completions./
command regex to provide completions for its own custom/
commands.@
can trigger completions from multiple completers; one may provide usernames of other users in the chat, and another may provide the context commands available in Jupyter AI (e.g.@file
).$
and returns the completion\\$
. Pressing "Enter" to accept the completion allows a user to easily type a literal dollar sign instead of opening math mode. If typing math was the user's intention, typing any character other than "Enter" hides the\\$
completion and allows math to be written./
or@
.Application: Define a completer that matches
./
following whitespace and returns filenames for the current directory. For example, this could trigger the completions./README.md
,./pyproject.toml
, etc.Application: Define a completer that matches
:
following whitespace and returns a list of emojis.Risks considered
This design proposes that the completer classes are defined in the backend. This may be a concern as some data & state is more easily accessed from the frontend.
get_completions()
method can be made async such that some completers can make a network call to use backend APIs, but others can use frontend APIs directly.I'm not sure if the current design will be sufficient for the
@
-mentioning of kernel local variables. This is a proposal for Jupyter AI v3.If a major revision of this design is needed, I will close this issue, revise the design, and open a new issue with a bumped revision number.
The text was updated successfully, but these errors were encountered: