├── .copier-answers.yml ├── .github └── workflows │ ├── build.yml │ ├── check-release.yml │ ├── deploy.yml │ ├── enforce-label.yml │ ├── prep-release.yml │ └── publish-release.yml ├── .gitignore ├── .prettierignore ├── .yarnrc.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── RELEASE.md ├── img ├── 1-extension-token.png ├── 2-api-key.png ├── 3-jupyterlab-dialog.png ├── 4-jupyterlab-settings.png └── 5-example.png ├── install.json ├── jupyterlab_codeium └── __init__.py ├── overrides.json ├── package.json ├── pyproject.toml ├── schema └── inline-provider.json ├── setup.py ├── src ├── api │ └── proto │ │ └── exa │ │ ├── codeium_common_pb │ │ └── codeium_common_pb.ts │ │ └── language_server_pb │ │ ├── language_server_connect.ts │ │ └── language_server_pb.ts ├── codeium.ts ├── config.ts ├── index.ts └── provider.ts ├── style ├── base.css ├── index.css └── index.js ├── tsconfig.json └── yarn.lock /.copier-answers.yml: -------------------------------------------------------------------------------- 1 | # Changes here will be overwritten by Copier; NEVER EDIT MANUALLY 2 | _commit: v4.3.1 3 | _src_path: https://github.com/jupyterlab/extension-template 4 | author_email: '' 5 | author_name: Jeremy Tuloup 6 | has_binder: false 7 | has_settings: true 8 | kind: frontend 9 | labextension_name: jupyterlab-codeium 10 | project_short_description: A JupyterLab extension to get AI code completion with codeium 11 | python_name: jupyterlab_codeium 12 | repository: https://github.com/jtpio/jupyterlab-codeium 13 | test: false 14 | 15 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: main 6 | pull_request: 7 | branches: '*' 8 | 9 | concurrency: 10 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 11 | cancel-in-progress: true 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v4 20 | 21 | - name: Base Setup 22 | uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 23 | 24 | - name: Install dependencies 25 | run: python -m pip install -U "jupyterlab>=4.0.0,<5" 26 | 27 | - name: Lint the extension 28 | run: | 29 | set -eux 30 | jlpm 31 | jlpm run lint:check 32 | 33 | - name: Build the extension 34 | run: | 35 | set -eux 36 | python -m pip install .[test] 37 | 38 | jupyter labextension list 39 | jupyter labextension list 2>&1 | grep -ie "jupyterlab-codeium.*OK" 40 | python -m jupyterlab.browser_check 41 | 42 | - name: Package the extension 43 | run: | 44 | set -eux 45 | 46 | pip install build 47 | python -m build 48 | pip uninstall -y "jupyterlab_codeium" jupyterlab 49 | 50 | - name: Upload extension packages 51 | uses: actions/upload-artifact@v4 52 | with: 53 | name: extension-artifacts 54 | path: dist/jupyterlab_codeium* 55 | if-no-files-found: error 56 | 57 | test_isolated: 58 | needs: build 59 | runs-on: ubuntu-latest 60 | 61 | steps: 62 | - name: Install Python 63 | uses: actions/setup-python@v5 64 | with: 65 | python-version: '3.9' 66 | architecture: 'x64' 67 | - uses: actions/download-artifact@v4 68 | with: 69 | name: extension-artifacts 70 | - name: Install and Test 71 | run: | 72 | set -eux 73 | # Remove NodeJS, twice to take care of system and locally installed node versions. 74 | sudo rm -rf $(which node) 75 | sudo rm -rf $(which node) 76 | 77 | pip install "jupyterlab>=4.0.0,<5" jupyterlab_codeium*.whl 78 | 79 | 80 | jupyter labextension list 81 | jupyter labextension list 2>&1 | grep -ie "jupyterlab-codeium.*OK" 82 | python -m jupyterlab.browser_check --no-browser-test 83 | 84 | 85 | check_links: 86 | name: Check Links 87 | runs-on: ubuntu-latest 88 | timeout-minutes: 15 89 | steps: 90 | - uses: actions/checkout@v4 91 | - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 92 | - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1 93 | -------------------------------------------------------------------------------- /.github/workflows/check-release.yml: -------------------------------------------------------------------------------- 1 | name: Check Release 2 | on: 3 | push: 4 | branches: ["main"] 5 | pull_request: 6 | branches: ["*"] 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 10 | cancel-in-progress: true 11 | 12 | jobs: 13 | check_release: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | - name: Base Setup 19 | uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 20 | - name: Check Release 21 | uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v2 22 | with: 23 | 24 | token: ${{ secrets.GITHUB_TOKEN }} 25 | 26 | - name: Upload Distributions 27 | uses: actions/upload-artifact@v4 28 | with: 29 | name: jupyterlab_codeium-releaser-dist-${{ github.run_number }} 30 | path: .jupyter_releaser_checkout/dist 31 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - '*' 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | - name: Setup Python 18 | uses: actions/setup-python@v5 19 | with: 20 | python-version: '3.11' 21 | - name: Install the dependencies 22 | run: | 23 | python -m pip install jupyterlite-core jupyterlite-pyodide-kernel 24 | 25 | # install a dev version of the extension 26 | python -m pip install . 27 | - name: Build the JupyterLite site 28 | run: | 29 | jupyter lite build --output-dir dist 30 | - name: Upload artifact 31 | uses: actions/upload-pages-artifact@v3 32 | with: 33 | path: ./dist 34 | 35 | deploy: 36 | needs: build 37 | if: github.ref == 'refs/heads/main' 38 | permissions: 39 | pages: write 40 | id-token: write 41 | 42 | environment: 43 | name: github-pages 44 | url: ${{ steps.deployment.outputs.page_url }} 45 | 46 | runs-on: ubuntu-latest 47 | steps: 48 | - name: Deploy to GitHub Pages 49 | id: deployment 50 | uses: actions/deploy-pages@v4 -------------------------------------------------------------------------------- /.github/workflows/enforce-label.yml: -------------------------------------------------------------------------------- 1 | name: Enforce PR label 2 | 3 | on: 4 | pull_request: 5 | types: [labeled, unlabeled, opened, edited, synchronize] 6 | jobs: 7 | enforce-label: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | pull-requests: write 11 | steps: 12 | - name: enforce-triage-label 13 | uses: jupyterlab/maintainer-tools/.github/actions/enforce-label@v1 14 | -------------------------------------------------------------------------------- /.github/workflows/prep-release.yml: -------------------------------------------------------------------------------- 1 | name: "Step 1: Prep Release" 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | version_spec: 6 | description: "New Version Specifier" 7 | default: "next" 8 | required: false 9 | branch: 10 | description: "The branch to target" 11 | required: false 12 | post_version_spec: 13 | description: "Post Version Specifier" 14 | required: false 15 | # silent: 16 | # description: "Set a placeholder in the changelog and don't publish the release." 17 | # required: false 18 | # type: boolean 19 | since: 20 | description: "Use PRs with activity since this date or git reference" 21 | required: false 22 | since_last_stable: 23 | description: "Use PRs with activity since the last stable git tag" 24 | required: false 25 | type: boolean 26 | jobs: 27 | prep_release: 28 | runs-on: ubuntu-latest 29 | permissions: 30 | contents: write 31 | steps: 32 | - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 33 | 34 | - name: Prep Release 35 | id: prep-release 36 | uses: jupyter-server/jupyter_releaser/.github/actions/prep-release@v2 37 | with: 38 | token: ${{ secrets.GITHUB_TOKEN }} 39 | version_spec: ${{ github.event.inputs.version_spec }} 40 | # silent: ${{ github.event.inputs.silent }} 41 | post_version_spec: ${{ github.event.inputs.post_version_spec }} 42 | branch: ${{ github.event.inputs.branch }} 43 | since: ${{ github.event.inputs.since }} 44 | since_last_stable: ${{ github.event.inputs.since_last_stable }} 45 | 46 | - name: "** Next Step **" 47 | run: | 48 | echo "Optional): Review Draft Release: ${{ steps.prep-release.outputs.release_url }}" 49 | -------------------------------------------------------------------------------- /.github/workflows/publish-release.yml: -------------------------------------------------------------------------------- 1 | name: "Step 2: Publish Release" 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | branch: 6 | description: "The target branch" 7 | required: false 8 | release_url: 9 | description: "The URL of the draft GitHub release" 10 | required: false 11 | steps_to_skip: 12 | description: "Comma separated list of steps to skip" 13 | required: false 14 | 15 | jobs: 16 | publish_release: 17 | runs-on: ubuntu-latest 18 | environment: release 19 | permissions: 20 | id-token: write 21 | steps: 22 | - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 23 | 24 | - uses: actions/create-github-app-token@v1 25 | id: app-token 26 | with: 27 | app-id: ${{ vars.APP_ID }} 28 | private-key: ${{ secrets.APP_PRIVATE_KEY }} 29 | 30 | - name: Populate Release 31 | id: populate-release 32 | uses: jupyter-server/jupyter_releaser/.github/actions/populate-release@v2 33 | with: 34 | token: ${{ steps.app-token.outputs.token }} 35 | branch: ${{ github.event.inputs.branch }} 36 | release_url: ${{ github.event.inputs.release_url }} 37 | steps_to_skip: ${{ github.event.inputs.steps_to_skip }} 38 | 39 | - name: Finalize Release 40 | id: finalize-release 41 | env: 42 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 43 | uses: jupyter-server/jupyter_releaser/.github/actions/finalize-release@v2 44 | with: 45 | token: ${{ steps.app-token.outputs.token }} 46 | release_url: ${{ steps.populate-release.outputs.release_url }} 47 | 48 | - name: "** Next Step **" 49 | if: ${{ success() }} 50 | run: | 51 | echo "Verify the final release" 52 | echo ${{ steps.finalize-release.outputs.release_url }} 53 | 54 | - name: "** Failure Message **" 55 | if: ${{ failure() }} 56 | run: | 57 | echo "Failed to Publish the Draft Release Url:" 58 | echo ${{ steps.populate-release.outputs.release_url }} 59 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.bundle.* 2 | lib/ 3 | node_modules/ 4 | *.log 5 | .eslintcache 6 | .stylelintcache 7 | *.egg-info/ 8 | .ipynb_checkpoints 9 | *.tsbuildinfo 10 | jupyterlab_codeium/labextension 11 | # Version file is handled by hatchling 12 | jupyterlab_codeium/_version.py 13 | 14 | # Created by https://www.gitignore.io/api/python 15 | # Edit at https://www.gitignore.io/?templates=python 16 | 17 | ### Python ### 18 | # Byte-compiled / optimized / DLL files 19 | __pycache__/ 20 | *.py[cod] 21 | *$py.class 22 | 23 | # C extensions 24 | *.so 25 | 26 | # Distribution / packaging 27 | .Python 28 | build/ 29 | develop-eggs/ 30 | dist/ 31 | downloads/ 32 | eggs/ 33 | .eggs/ 34 | lib/ 35 | lib64/ 36 | parts/ 37 | sdist/ 38 | var/ 39 | wheels/ 40 | pip-wheel-metadata/ 41 | share/python-wheels/ 42 | .installed.cfg 43 | *.egg 44 | MANIFEST 45 | 46 | # PyInstaller 47 | # Usually these files are written by a python script from a template 48 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 49 | *.manifest 50 | *.spec 51 | 52 | # Installer logs 53 | pip-log.txt 54 | pip-delete-this-directory.txt 55 | 56 | # Unit test / coverage reports 57 | htmlcov/ 58 | .tox/ 59 | .nox/ 60 | .coverage 61 | .coverage.* 62 | .cache 63 | nosetests.xml 64 | coverage/ 65 | coverage.xml 66 | *.cover 67 | .hypothesis/ 68 | .pytest_cache/ 69 | 70 | # Translations 71 | *.mo 72 | *.pot 73 | 74 | # Scrapy stuff: 75 | .scrapy 76 | 77 | # Sphinx documentation 78 | docs/_build/ 79 | 80 | # PyBuilder 81 | target/ 82 | 83 | # pyenv 84 | .python-version 85 | 86 | # celery beat schedule file 87 | celerybeat-schedule 88 | 89 | # SageMath parsed files 90 | *.sage.py 91 | 92 | # Spyder project settings 93 | .spyderproject 94 | .spyproject 95 | 96 | # Rope project settings 97 | .ropeproject 98 | 99 | # Mr Developer 100 | .mr.developer.cfg 101 | .project 102 | .pydevproject 103 | 104 | # mkdocs documentation 105 | /site 106 | 107 | # mypy 108 | .mypy_cache/ 109 | .dmypy.json 110 | dmypy.json 111 | 112 | # Pyre type checker 113 | .pyre/ 114 | 115 | # End of https://www.gitignore.io/api/python 116 | 117 | # OSX files 118 | .DS_Store 119 | 120 | # Yarn cache 121 | .yarn/ 122 | 123 | Untitled*.ipynb 124 | .vscode 125 | 126 | # JupyterLite 127 | _output 128 | *.doit.db 129 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | **/node_modules 3 | **/lib 4 | **/package.json 5 | !/package.json 6 | jupyterlab_codeium 7 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | 4 | 5 | ## 0.1.1 6 | 7 | ([Full Changelog](https://github.com/jtpio/jupyterlab-codeium/compare/v0.1.0...d2eb596d8dd368815125fcb71b3f027e8ef3c119)) 8 | 9 | ### Enhancements made 10 | 11 | - Remove dialog [#7](https://github.com/jtpio/jupyterlab-codeium/pull/7) ([@jtpio](https://github.com/jtpio)) 12 | 13 | ### Documentation improvements 14 | 15 | - Set up playground defaults [#6](https://github.com/jtpio/jupyterlab-codeium/pull/6) ([@jtpio](https://github.com/jtpio)) 16 | 17 | ### Contributors to this release 18 | 19 | ([GitHub contributors page for this release](https://github.com/jtpio/jupyterlab-codeium/graphs/contributors?from=2024-06-04&to=2024-06-26&type=c)) 20 | 21 | [@jtpio](https://github.com/search?q=repo%3Ajtpio%2Fjupyterlab-codeium+involves%3Ajtpio+updated%3A2024-06-04..2024-06-26&type=Issues) 22 | 23 | 24 | 25 | ## 0.1.0 26 | 27 | ([Full Changelog](https://github.com/jtpio/jupyterlab-codeium/compare/5e6049da035a16249e8784e0037c3c4802974d90...6c748933be3fd695d807e5d43bb1580e80ddd841)) 28 | 29 | ### Enhancements made 30 | 31 | - Fix handling of languages [#4](https://github.com/jtpio/jupyterlab-codeium/pull/4) ([@jtpio](https://github.com/jtpio)) 32 | 33 | ### Documentation improvements 34 | 35 | - Add files for a JupyterLite demo [#1](https://github.com/jtpio/jupyterlab-codeium/pull/1) ([@jtpio](https://github.com/jtpio)) 36 | 37 | ### Contributors to this release 38 | 39 | ([GitHub contributors page for this release](https://github.com/jtpio/jupyterlab-codeium/graphs/contributors?from=2024-06-03&to=2024-06-04&type=c)) 40 | 41 | [@jtpio](https://github.com/search?q=repo%3Ajtpio%2Fjupyterlab-codeium+involves%3Ajtpio+updated%3A2024-06-03..2024-06-04&type=Issues) 42 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Development install 4 | 5 | Note: You will need NodeJS to build the extension package. 6 | 7 | The `jlpm` command is JupyterLab's pinned version of 8 | [yarn](https://yarnpkg.com/) that is installed with JupyterLab. You may use 9 | `yarn` or `npm` in lieu of `jlpm` below. 10 | 11 | ```bash 12 | # Clone the repo to your local environment 13 | # Change directory to the jupyterlab_codeium directory 14 | # Install package in development mode 15 | pip install -e "." 16 | # Link your development version of the extension with JupyterLab 17 | jupyter labextension develop . --overwrite 18 | # Rebuild extension Typescript source after making changes 19 | jlpm build 20 | ``` 21 | 22 | You can watch the source directory and run JupyterLab at the same time in different terminals to watch for changes in the extension's source and automatically rebuild the extension. 23 | 24 | ```bash 25 | # Watch the source directory in one terminal, automatically rebuilding when needed 26 | jlpm watch 27 | # Run JupyterLab in another terminal 28 | jupyter lab 29 | ``` 30 | 31 | With the watch command running, every saved change will immediately be built locally and available in your running JupyterLab. Refresh JupyterLab to load the change in your browser (you may need to wait several seconds for the extension to be rebuilt). 32 | 33 | By default, the `jlpm build` command generates the source maps for this extension to make it easier to debug using the browser dev tools. To also generate source maps for the JupyterLab core extensions, you can run the following command: 34 | 35 | ```bash 36 | jupyter lab build --minimize=False 37 | ``` 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2024, Jeremy Tuloup 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | Copyright (c) 2024, Val Town 32 | 33 | Permission to use, copy, modify, and/or distribute this software for any 34 | purpose with or without fee is hereby granted, provided that the above 35 | copyright notice and this permission notice appear in all copies. 36 | 37 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 38 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 39 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 40 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 41 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 42 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 43 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 44 | 45 | Contains parts of modeling-app, licensed under the MIT License, 46 | Copyright (c) 2023 The Zoo Authors 47 | 48 | Contains parts of Cursor, licensed under the MIT License, 49 | Copyright (c) 2023 Cursor AI, Inc. 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jupyterlab-codeium 2 | 3 | [![Github Actions Status](https://github.com/jtpio/jupyterlab-codeium/workflows/Build/badge.svg)](https://github.com/jtpio/jupyterlab-codeium/actions/workflows/build.yml) 4 | [![lite-badge](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)](https://jtpio.github.io/jupyterlab-codeium/lab/index.html) 5 | 6 | JupyterLab extension to get AI code completions with [Codeium](https://codeium.com/). 7 | 8 | https://github.com/jtpio/jupyterlab-codeium/assets/591645/7ec0a6fa-9c51-49a8-89b4-77b431f4bda9 9 | 10 | > [!WARNING] 11 | > The Codeium team forked this repo to continue the development: https://github.com/Exafunction/codeium.jupyter 12 | 13 | > [!WARNING] 14 | > This extension is still very much experimental. It is not an official Codeium extension. 15 | 16 | ## ✨ Try it in your browser ✨ 17 | 18 | 1. Follow the instructions in the [Usage](#usage) section to get your API key. 19 | 2. Open https://jtpio.github.io/jupyterlab-codeium in your browser 20 | 21 | ## Requirements 22 | 23 | - JupyterLab >= 4.1.0 24 | 25 | > [!NOTE] 26 | > This extension is also compatible with [JupyterLite](https://github.com/jupyterlite/jupyterlite) >= 0.3.0 27 | 28 | ## Install 29 | 30 | To install the extension, execute: 31 | 32 | ```bash 33 | pip install jupyterlab-codeium 34 | ``` 35 | 36 | ## Usage 37 | 38 | > [!WARNING] 39 | > Setting up the extension requires a Codeium API key. This part might still be challenging as retrieving the key requires a few manual steps at the moment. 40 | > This might later be improved by providing a better auth flow. 41 | 42 | 1. Go to the Codeium website and sign up for an account: https://codeium.com/ 43 | 2. Install the browser extension: https://codeium.com/chrome_tutorial 44 | 3. Open the settings for the chrome extension and click on "Get Token" 45 | 46 | ![Get Token](./img/1-extension-token.png) 47 | 48 | 4. Right click on the extension window and select "Inspect" to open the dev tools for the extension. Then click on "Network" 49 | 5. Copy the token and paste it the input area, and then press "Enter Token" 50 | 6. This should log a new API request in the network tab. Click on "Preview" to get the API key. 51 | 52 | ![Enter Token](./img/2-api-key.png) 53 | 54 | 7. Go to the settings to paste the API key: 55 | 56 | ![Settings](./img/4-jupyterlab-settings.png) 57 | 58 | 8. You should now be able to use the extension. Open a Python file and start typing to see the completions. 59 | 60 | ![Completions](./img/5-example.png) 61 | 62 | ## Contributing 63 | 64 | ### Packaging and releasing the extension 65 | 66 | See [RELEASE](RELEASE.md) 67 | 68 | ### Credits 69 | 70 | Many thanks to the `codemirror-codeium` project for the inspiration and the initial implementation of the Codeium integration with CodeMirror 6: https://github.com/val-town/codemirror-codeium 71 | 72 | The protobuf files were copied from that repo and reused as is in this project. 73 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # Making a new release of jupyterlab_codeium 2 | 3 | The extension can be published to `PyPI` and `npm` manually or using the [Jupyter Releaser](https://github.com/jupyter-server/jupyter_releaser). 4 | 5 | ## Manual release 6 | 7 | ### Python package 8 | 9 | This extension can be distributed as Python packages. All of the Python 10 | packaging instructions are in the `pyproject.toml` file to wrap your extension in a 11 | Python package. Before generating a package, you first need to install some tools: 12 | 13 | ```bash 14 | pip install build twine hatch 15 | ``` 16 | 17 | Bump the version using `hatch`. By default this will create a tag. 18 | See the docs on [hatch-nodejs-version](https://github.com/agoose77/hatch-nodejs-version#semver) for details. 19 | 20 | ```bash 21 | hatch version 22 | ``` 23 | 24 | Make sure to clean up all the development files before building the package: 25 | 26 | ```bash 27 | jlpm clean:all 28 | ``` 29 | 30 | You could also clean up the local git repository: 31 | 32 | ```bash 33 | git clean -dfX 34 | ``` 35 | 36 | To create a Python source package (`.tar.gz`) and the binary package (`.whl`) in the `dist/` directory, do: 37 | 38 | ```bash 39 | python -m build 40 | ``` 41 | 42 | > `python setup.py sdist bdist_wheel` is deprecated and will not work for this package. 43 | 44 | Then to upload the package to PyPI, do: 45 | 46 | ```bash 47 | twine upload dist/* 48 | ``` 49 | 50 | ### NPM package 51 | 52 | To publish the frontend part of the extension as a NPM package, do: 53 | 54 | ```bash 55 | npm login 56 | npm publish --access public 57 | ``` 58 | 59 | ## Automated releases with the Jupyter Releaser 60 | 61 | The extension repository should already be compatible with the Jupyter Releaser. But 62 | the GitHub repository and the package managers need to be properly set up. Please 63 | follow the instructions of the Jupyter Releaser [checklist](https://jupyter-releaser.readthedocs.io/en/latest/how_to_guides/convert_repo_from_repo.html). 64 | 65 | Here is a summary of the steps to cut a new release: 66 | 67 | - Go to the Actions panel 68 | - Run the "Step 1: Prep Release" workflow 69 | - Check the draft changelog 70 | - Run the "Step 2: Publish Release" workflow 71 | 72 | > [!NOTE] 73 | > Check out the [workflow documentation](https://jupyter-releaser.readthedocs.io/en/latest/get_started/making_release_from_repo.html) 74 | > for more information. 75 | 76 | ## Publishing to `conda-forge` 77 | 78 | If the package is not on conda forge yet, check the documentation to learn how to add it: https://conda-forge.org/docs/maintainer/adding_pkgs.html 79 | 80 | Otherwise a bot should pick up the new version publish to PyPI, and open a new PR on the feedstock repository automatically. 81 | -------------------------------------------------------------------------------- /img/1-extension-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jtpio/jupyterlab-codeium/76cf2e4255ba4d959348c4794a07d1b30750fd14/img/1-extension-token.png -------------------------------------------------------------------------------- /img/2-api-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jtpio/jupyterlab-codeium/76cf2e4255ba4d959348c4794a07d1b30750fd14/img/2-api-key.png -------------------------------------------------------------------------------- /img/3-jupyterlab-dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jtpio/jupyterlab-codeium/76cf2e4255ba4d959348c4794a07d1b30750fd14/img/3-jupyterlab-dialog.png -------------------------------------------------------------------------------- /img/4-jupyterlab-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jtpio/jupyterlab-codeium/76cf2e4255ba4d959348c4794a07d1b30750fd14/img/4-jupyterlab-settings.png -------------------------------------------------------------------------------- /img/5-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jtpio/jupyterlab-codeium/76cf2e4255ba4d959348c4794a07d1b30750fd14/img/5-example.png -------------------------------------------------------------------------------- /install.json: -------------------------------------------------------------------------------- 1 | { 2 | "packageManager": "python", 3 | "packageName": "jupyterlab_codeium", 4 | "uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package jupyterlab_codeium" 5 | } 6 | -------------------------------------------------------------------------------- /jupyterlab_codeium/__init__.py: -------------------------------------------------------------------------------- 1 | try: 2 | from ._version import __version__ 3 | except ImportError: 4 | # Fallback when using the package in dev mode without installing 5 | # in editable mode with pip. It is highly recommended to install 6 | # the package from a stable release or in editable mode: https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs 7 | import warnings 8 | warnings.warn("Importing 'jupyterlab_codeium' outside a proper installation.") 9 | __version__ = "dev" 10 | 11 | 12 | def _jupyter_labextension_paths(): 13 | return [{ 14 | "src": "labextension", 15 | "dest": "jupyterlab-codeium" 16 | }] 17 | -------------------------------------------------------------------------------- /overrides.json: -------------------------------------------------------------------------------- 1 | { 2 | "jupyterlab-codeium:inline-provider": { 3 | "apiKey": "d49954eb-cfba-4992-980f-d8fb37f0e942" 4 | }, 5 | "@jupyterlab/shortcuts-extension:shortcuts": { 6 | "shortcuts": [ 7 | { 8 | "command": "inline-completer:accept", 9 | "selector": ".jp-mod-inline-completer-active", 10 | "keys": ["Tab"] 11 | } 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jupyterlab-codeium", 3 | "version": "0.1.1", 4 | "description": "A JupyterLab extension to get AI code completions with Codeium", 5 | "keywords": [ 6 | "jupyter", 7 | "jupyterlab", 8 | "jupyterlab-extension" 9 | ], 10 | "homepage": "https://github.com/jtpio/jupyterlab-codeium", 11 | "bugs": { 12 | "url": "https://github.com/jtpio/jupyterlab-codeium/issues" 13 | }, 14 | "license": "BSD-3-Clause", 15 | "author": "Jeremy Tuloup", 16 | "files": [ 17 | "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}", 18 | "style/**/*.{css,js,eot,gif,html,jpg,json,png,svg,woff2,ttf}", 19 | "src/**/*.{ts,tsx}", 20 | "schema/*.json" 21 | ], 22 | "main": "lib/index.js", 23 | "types": "lib/index.d.ts", 24 | "style": "style/index.css", 25 | "repository": { 26 | "type": "git", 27 | "url": "https://github.com/jtpio/jupyterlab-codeium.git" 28 | }, 29 | "scripts": { 30 | "build": "jlpm build:lib && jlpm build:labextension:dev", 31 | "build:prod": "jlpm clean && jlpm build:lib:prod && jlpm build:labextension", 32 | "build:labextension": "jupyter labextension build .", 33 | "build:labextension:dev": "jupyter labextension build --development True .", 34 | "build:lib": "tsc --sourceMap", 35 | "build:lib:prod": "tsc", 36 | "clean": "jlpm clean:lib", 37 | "clean:lib": "rimraf lib tsconfig.tsbuildinfo", 38 | "clean:lintcache": "rimraf .eslintcache .stylelintcache", 39 | "clean:labextension": "rimraf jupyterlab_codeium/labextension jupyterlab_codeium/_version.py", 40 | "clean:all": "jlpm clean:lib && jlpm clean:labextension && jlpm clean:lintcache", 41 | "eslint": "jlpm eslint:check --fix", 42 | "eslint:check": "eslint . --cache --ext .ts,.tsx", 43 | "install:extension": "jlpm build", 44 | "lint": "jlpm stylelint && jlpm prettier && jlpm eslint", 45 | "lint:check": "jlpm stylelint:check && jlpm prettier:check && jlpm eslint:check", 46 | "prettier": "jlpm prettier:base --write --list-different", 47 | "prettier:base": "prettier \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md}\"", 48 | "prettier:check": "jlpm prettier:base --check", 49 | "stylelint": "jlpm stylelint:check --fix", 50 | "stylelint:check": "stylelint --cache \"style/**/*.css\"", 51 | "watch": "run-p watch:src watch:labextension", 52 | "watch:src": "tsc -w --sourceMap", 53 | "watch:labextension": "jupyter labextension watch ." 54 | }, 55 | "dependencies": { 56 | "@connectrpc/connect": "^1.4.0", 57 | "@connectrpc/connect-web": "^1.4.0", 58 | "@jupyterlab/application": "^4.0.0", 59 | "@jupyterlab/codemirror": "^4.0.0", 60 | "@jupyterlab/completer": "^4.0.0", 61 | "@jupyterlab/settingregistry": "^4.0.0", 62 | "@lumino/coreutils": "^2.1.2" 63 | }, 64 | "devDependencies": { 65 | "@bufbuild/buf": "^1.30.0", 66 | "@bufbuild/protobuf": "^1.8.0", 67 | "@jupyterlab/builder": "^4.0.0", 68 | "@types/json-schema": "^7.0.11", 69 | "@types/react": "^18.0.26", 70 | "@types/react-addons-linked-state-mixin": "^0.14.22", 71 | "@typescript-eslint/eslint-plugin": "^6.1.0", 72 | "@typescript-eslint/parser": "^6.1.0", 73 | "css-loader": "^6.7.1", 74 | "eslint": "^8.36.0", 75 | "eslint-config-prettier": "^8.8.0", 76 | "eslint-plugin-prettier": "^5.0.0", 77 | "npm-run-all": "^4.1.5", 78 | "prettier": "^3.0.0", 79 | "rimraf": "^5.0.1", 80 | "source-map-loader": "^1.0.2", 81 | "style-loader": "^3.3.1", 82 | "stylelint": "^15.10.1", 83 | "stylelint-config-recommended": "^13.0.0", 84 | "stylelint-config-standard": "^34.0.0", 85 | "stylelint-csstree-validator": "^3.0.0", 86 | "stylelint-prettier": "^4.0.0", 87 | "typescript": "~5.0.2", 88 | "yjs": "^13.5.0" 89 | }, 90 | "sideEffects": [ 91 | "style/*.css", 92 | "style/index.js" 93 | ], 94 | "styleModule": "style/index.js", 95 | "publishConfig": { 96 | "access": "public" 97 | }, 98 | "jupyterlab": { 99 | "extension": true, 100 | "outputDir": "jupyterlab_codeium/labextension", 101 | "schemaDir": "schema" 102 | }, 103 | "eslintIgnore": [ 104 | "node_modules", 105 | "dist", 106 | "coverage", 107 | "**/*.d.ts" 108 | ], 109 | "eslintConfig": { 110 | "extends": [ 111 | "eslint:recommended", 112 | "plugin:@typescript-eslint/eslint-recommended", 113 | "plugin:@typescript-eslint/recommended", 114 | "plugin:prettier/recommended" 115 | ], 116 | "parser": "@typescript-eslint/parser", 117 | "parserOptions": { 118 | "project": "tsconfig.json", 119 | "sourceType": "module" 120 | }, 121 | "plugins": [ 122 | "@typescript-eslint" 123 | ], 124 | "rules": { 125 | "@typescript-eslint/naming-convention": [ 126 | "error", 127 | { 128 | "selector": "interface", 129 | "format": [ 130 | "PascalCase" 131 | ], 132 | "custom": { 133 | "regex": "^I[A-Z]", 134 | "match": true 135 | } 136 | } 137 | ], 138 | "@typescript-eslint/no-unused-vars": [ 139 | "warn", 140 | { 141 | "args": "none" 142 | } 143 | ], 144 | "@typescript-eslint/no-explicit-any": "off", 145 | "@typescript-eslint/no-namespace": "off", 146 | "@typescript-eslint/no-use-before-define": "off", 147 | "@typescript-eslint/quotes": [ 148 | "error", 149 | "single", 150 | { 151 | "avoidEscape": true, 152 | "allowTemplateLiterals": false 153 | } 154 | ], 155 | "curly": [ 156 | "error", 157 | "all" 158 | ], 159 | "eqeqeq": "error", 160 | "prefer-arrow-callback": "error" 161 | } 162 | }, 163 | "prettier": { 164 | "singleQuote": true, 165 | "trailingComma": "none", 166 | "arrowParens": "avoid", 167 | "endOfLine": "auto", 168 | "overrides": [ 169 | { 170 | "files": "package.json", 171 | "options": { 172 | "tabWidth": 4 173 | } 174 | } 175 | ] 176 | }, 177 | "stylelint": { 178 | "extends": [ 179 | "stylelint-config-recommended", 180 | "stylelint-config-standard", 181 | "stylelint-prettier/recommended" 182 | ], 183 | "plugins": [ 184 | "stylelint-csstree-validator" 185 | ], 186 | "rules": { 187 | "csstree/validator": true, 188 | "property-no-vendor-prefix": null, 189 | "selector-class-pattern": "^([a-z][A-z\\d]*)(-[A-z\\d]+)*$", 190 | "selector-no-vendor-prefix": null, 191 | "value-no-vendor-prefix": null 192 | } 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["hatchling>=1.5.0", "jupyterlab>=4.0.0,<5", "hatch-nodejs-version>=0.3.2"] 3 | build-backend = "hatchling.build" 4 | 5 | [project] 6 | name = "jupyterlab_codeium" 7 | readme = "README.md" 8 | license = { file = "LICENSE" } 9 | requires-python = ">=3.8" 10 | classifiers = [ 11 | "Framework :: Jupyter", 12 | "Framework :: Jupyter :: JupyterLab", 13 | "Framework :: Jupyter :: JupyterLab :: 4", 14 | "Framework :: Jupyter :: JupyterLab :: Extensions", 15 | "Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt", 16 | "License :: OSI Approved :: BSD License", 17 | "Programming Language :: Python", 18 | "Programming Language :: Python :: 3", 19 | "Programming Language :: Python :: 3.8", 20 | "Programming Language :: Python :: 3.9", 21 | "Programming Language :: Python :: 3.10", 22 | "Programming Language :: Python :: 3.11", 23 | "Programming Language :: Python :: 3.12", 24 | ] 25 | dependencies = [ 26 | ] 27 | dynamic = ["version", "description", "authors", "urls", "keywords"] 28 | 29 | [tool.hatch.version] 30 | source = "nodejs" 31 | 32 | [tool.hatch.metadata.hooks.nodejs] 33 | fields = ["description", "authors", "urls"] 34 | 35 | [tool.hatch.build.targets.sdist] 36 | artifacts = ["jupyterlab_codeium/labextension"] 37 | exclude = [".github", "binder"] 38 | 39 | [tool.hatch.build.targets.wheel.shared-data] 40 | "jupyterlab_codeium/labextension" = "share/jupyter/labextensions/jupyterlab-codeium" 41 | "install.json" = "share/jupyter/labextensions/jupyterlab-codeium/install.json" 42 | 43 | [tool.hatch.build.hooks.version] 44 | path = "jupyterlab_codeium/_version.py" 45 | 46 | [tool.hatch.build.hooks.jupyter-builder] 47 | dependencies = ["hatch-jupyter-builder>=0.5"] 48 | build-function = "hatch_jupyter_builder.npm_builder" 49 | ensured-targets = [ 50 | "jupyterlab_codeium/labextension/static/style.js", 51 | "jupyterlab_codeium/labextension/package.json", 52 | ] 53 | skip-if-exists = ["jupyterlab_codeium/labextension/static/style.js"] 54 | 55 | [tool.hatch.build.hooks.jupyter-builder.build-kwargs] 56 | build_cmd = "build:prod" 57 | npm = ["jlpm"] 58 | 59 | [tool.hatch.build.hooks.jupyter-builder.editable-build-kwargs] 60 | build_cmd = "install:extension" 61 | npm = ["jlpm"] 62 | source_dir = "src" 63 | build_dir = "jupyterlab_codeium/labextension" 64 | 65 | [tool.jupyter-releaser.options] 66 | version_cmd = "hatch version" 67 | 68 | [tool.jupyter-releaser.hooks] 69 | before-build-npm = [ 70 | "python -m pip install 'jupyterlab>=4.0.0,<5'", 71 | "jlpm", 72 | "jlpm build:prod" 73 | ] 74 | before-build-python = ["jlpm clean:all"] 75 | 76 | [tool.check-wheel-contents] 77 | ignore = ["W002"] 78 | -------------------------------------------------------------------------------- /schema/inline-provider.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Codeium", 3 | "description": "Codeuim settings", 4 | "type": "object", 5 | "properties": { 6 | "apiKey": { 7 | "type": "string", 8 | "title": "The Codeium API key", 9 | "description": "The API key to use for Codeium", 10 | "default": "" 11 | } 12 | }, 13 | "additionalProperties": false 14 | } 15 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | __import__("setuptools").setup() 2 | -------------------------------------------------------------------------------- /src/api/proto/exa/codeium_common_pb/codeium_common_pb.ts: -------------------------------------------------------------------------------- 1 | // Copyright Exafunction, Inc. 2 | 3 | // @generated by protoc-gen-es v1.4.2 with parameter "target=ts" 4 | // @generated from file exa/codeium_common_pb/codeium_common.proto (package exa.codeium_common_pb, syntax proto3) 5 | /* eslint-disable */ 6 | // @ts-nocheck 7 | 8 | import type { 9 | BinaryReadOptions, 10 | FieldList, 11 | JsonReadOptions, 12 | JsonValue, 13 | PartialMessage, 14 | PlainMessage 15 | } from '@bufbuild/protobuf'; 16 | import { Message, proto3, protoInt64 } from '@bufbuild/protobuf'; 17 | 18 | /** 19 | * @generated from enum exa.codeium_common_pb.ExperimentKey 20 | */ 21 | export enum ExperimentKey { 22 | /** 23 | * @generated from enum value: UNSPECIFIED = 0; 24 | */ 25 | UNSPECIFIED = 0, 26 | 27 | /** 28 | * @generated from enum value: JUPYTER_FORMAT = 77; 29 | */ 30 | JUPYTER_FORMAT = 77 31 | } 32 | // Retrieve enum metadata with: proto3.getEnumType(ExperimentKey) 33 | proto3.util.setEnumType(ExperimentKey, 'exa.codeium_common_pb.ExperimentKey', [ 34 | { no: 0, name: 'UNSPECIFIED' }, 35 | { no: 77, name: 'JUPYTER_FORMAT' } 36 | ]); 37 | 38 | /** 39 | * Authentication source for users on the cloud service. 40 | * 41 | * @generated from enum exa.codeium_common_pb.AuthSource 42 | */ 43 | export enum AuthSource { 44 | /** 45 | * @generated from enum value: AUTH_SOURCE_CODEIUM = 0; 46 | */ 47 | CODEIUM = 0 48 | } 49 | // Retrieve enum metadata with: proto3.getEnumType(AuthSource) 50 | proto3.util.setEnumType(AuthSource, 'exa.codeium_common_pb.AuthSource', [ 51 | { no: 0, name: 'AUTH_SOURCE_CODEIUM' } 52 | ]); 53 | 54 | /** 55 | * @generated from enum exa.codeium_common_pb.EventType 56 | */ 57 | export enum EventType { 58 | /** 59 | * @generated from enum value: EVENT_TYPE_UNSPECIFIED = 0; 60 | */ 61 | UNSPECIFIED = 0, 62 | 63 | /** 64 | * @generated from enum value: EVENT_TYPE_ENABLE_CODEIUM = 1; 65 | */ 66 | ENABLE_CODEIUM = 1, 67 | 68 | /** 69 | * @generated from enum value: EVENT_TYPE_DISABLE_CODEIUM = 2; 70 | */ 71 | DISABLE_CODEIUM = 2, 72 | 73 | /** 74 | * @generated from enum value: EVENT_TYPE_SHOW_PREVIOUS_COMPLETION = 3; 75 | */ 76 | SHOW_PREVIOUS_COMPLETION = 3, 77 | 78 | /** 79 | * @generated from enum value: EVENT_TYPE_SHOW_NEXT_COMPLETION = 4; 80 | */ 81 | SHOW_NEXT_COMPLETION = 4 82 | } 83 | // Retrieve enum metadata with: proto3.getEnumType(EventType) 84 | proto3.util.setEnumType(EventType, 'exa.codeium_common_pb.EventType', [ 85 | { no: 0, name: 'EVENT_TYPE_UNSPECIFIED' }, 86 | { no: 1, name: 'EVENT_TYPE_ENABLE_CODEIUM' }, 87 | { no: 2, name: 'EVENT_TYPE_DISABLE_CODEIUM' }, 88 | { no: 3, name: 'EVENT_TYPE_SHOW_PREVIOUS_COMPLETION' }, 89 | { no: 4, name: 'EVENT_TYPE_SHOW_NEXT_COMPLETION' } 90 | ]); 91 | 92 | /** 93 | * @generated from enum exa.codeium_common_pb.CompletionSource 94 | */ 95 | export enum CompletionSource { 96 | /** 97 | * @generated from enum value: COMPLETION_SOURCE_UNSPECIFIED = 0; 98 | */ 99 | UNSPECIFIED = 0, 100 | 101 | /** 102 | * @generated from enum value: COMPLETION_SOURCE_TYPING_AS_SUGGESTED = 1; 103 | */ 104 | TYPING_AS_SUGGESTED = 1, 105 | 106 | /** 107 | * @generated from enum value: COMPLETION_SOURCE_CACHE = 2; 108 | */ 109 | CACHE = 2, 110 | 111 | /** 112 | * @generated from enum value: COMPLETION_SOURCE_NETWORK = 3; 113 | */ 114 | NETWORK = 3 115 | } 116 | // Retrieve enum metadata with: proto3.getEnumType(CompletionSource) 117 | proto3.util.setEnumType( 118 | CompletionSource, 119 | 'exa.codeium_common_pb.CompletionSource', 120 | [ 121 | { no: 0, name: 'COMPLETION_SOURCE_UNSPECIFIED' }, 122 | { no: 1, name: 'COMPLETION_SOURCE_TYPING_AS_SUGGESTED' }, 123 | { no: 2, name: 'COMPLETION_SOURCE_CACHE' }, 124 | { no: 3, name: 'COMPLETION_SOURCE_NETWORK' } 125 | ] 126 | ); 127 | 128 | /** 129 | * Every time this list is updated, we should be redeploying the API server 130 | * since it uses the string representation for BQ. 131 | * 132 | * @generated from enum exa.codeium_common_pb.Language 133 | */ 134 | export enum Language { 135 | /** 136 | * @generated from enum value: LANGUAGE_UNSPECIFIED = 0; 137 | */ 138 | UNSPECIFIED = 0, 139 | 140 | /** 141 | * @generated from enum value: LANGUAGE_C = 1; 142 | */ 143 | C = 1, 144 | 145 | /** 146 | * @generated from enum value: LANGUAGE_CLOJURE = 2; 147 | */ 148 | CLOJURE = 2, 149 | 150 | /** 151 | * @generated from enum value: LANGUAGE_COFFEESCRIPT = 3; 152 | */ 153 | COFFEESCRIPT = 3, 154 | 155 | /** 156 | * @generated from enum value: LANGUAGE_CPP = 4; 157 | */ 158 | CPP = 4, 159 | 160 | /** 161 | * @generated from enum value: LANGUAGE_CSHARP = 5; 162 | */ 163 | CSHARP = 5, 164 | 165 | /** 166 | * @generated from enum value: LANGUAGE_CSS = 6; 167 | */ 168 | CSS = 6, 169 | 170 | /** 171 | * @generated from enum value: LANGUAGE_CUDACPP = 7; 172 | */ 173 | CUDACPP = 7, 174 | 175 | /** 176 | * @generated from enum value: LANGUAGE_DOCKERFILE = 8; 177 | */ 178 | DOCKERFILE = 8, 179 | 180 | /** 181 | * @generated from enum value: LANGUAGE_GO = 9; 182 | */ 183 | GO = 9, 184 | 185 | /** 186 | * @generated from enum value: LANGUAGE_GROOVY = 10; 187 | */ 188 | GROOVY = 10, 189 | 190 | /** 191 | * @generated from enum value: LANGUAGE_HANDLEBARS = 11; 192 | */ 193 | HANDLEBARS = 11, 194 | 195 | /** 196 | * @generated from enum value: LANGUAGE_HASKELL = 12; 197 | */ 198 | HASKELL = 12, 199 | 200 | /** 201 | * @generated from enum value: LANGUAGE_HCL = 13; 202 | */ 203 | HCL = 13, 204 | 205 | /** 206 | * @generated from enum value: LANGUAGE_HTML = 14; 207 | */ 208 | HTML = 14, 209 | 210 | /** 211 | * @generated from enum value: LANGUAGE_INI = 15; 212 | */ 213 | INI = 15, 214 | 215 | /** 216 | * @generated from enum value: LANGUAGE_JAVA = 16; 217 | */ 218 | JAVA = 16, 219 | 220 | /** 221 | * @generated from enum value: LANGUAGE_JAVASCRIPT = 17; 222 | */ 223 | JAVASCRIPT = 17, 224 | 225 | /** 226 | * @generated from enum value: LANGUAGE_JSON = 18; 227 | */ 228 | JSON = 18, 229 | 230 | /** 231 | * @generated from enum value: LANGUAGE_JULIA = 19; 232 | */ 233 | JULIA = 19, 234 | 235 | /** 236 | * @generated from enum value: LANGUAGE_KOTLIN = 20; 237 | */ 238 | KOTLIN = 20, 239 | 240 | /** 241 | * @generated from enum value: LANGUAGE_LATEX = 21; 242 | */ 243 | LATEX = 21, 244 | 245 | /** 246 | * @generated from enum value: LANGUAGE_LESS = 22; 247 | */ 248 | LESS = 22, 249 | 250 | /** 251 | * @generated from enum value: LANGUAGE_LUA = 23; 252 | */ 253 | LUA = 23, 254 | 255 | /** 256 | * @generated from enum value: LANGUAGE_MAKEFILE = 24; 257 | */ 258 | MAKEFILE = 24, 259 | 260 | /** 261 | * @generated from enum value: LANGUAGE_MARKDOWN = 25; 262 | */ 263 | MARKDOWN = 25, 264 | 265 | /** 266 | * @generated from enum value: LANGUAGE_OBJECTIVEC = 26; 267 | */ 268 | OBJECTIVEC = 26, 269 | 270 | /** 271 | * @generated from enum value: LANGUAGE_OBJECTIVECPP = 27; 272 | */ 273 | OBJECTIVECPP = 27, 274 | 275 | /** 276 | * @generated from enum value: LANGUAGE_PERL = 28; 277 | */ 278 | PERL = 28, 279 | 280 | /** 281 | * @generated from enum value: LANGUAGE_PHP = 29; 282 | */ 283 | PHP = 29, 284 | 285 | /** 286 | * @generated from enum value: LANGUAGE_PLAINTEXT = 30; 287 | */ 288 | PLAINTEXT = 30, 289 | 290 | /** 291 | * @generated from enum value: LANGUAGE_PROTOBUF = 31; 292 | */ 293 | PROTOBUF = 31, 294 | 295 | /** 296 | * @generated from enum value: LANGUAGE_PBTXT = 32; 297 | */ 298 | PBTXT = 32, 299 | 300 | /** 301 | * @generated from enum value: LANGUAGE_PYTHON = 33; 302 | */ 303 | PYTHON = 33, 304 | 305 | /** 306 | * @generated from enum value: LANGUAGE_R = 34; 307 | */ 308 | R = 34, 309 | 310 | /** 311 | * @generated from enum value: LANGUAGE_RUBY = 35; 312 | */ 313 | RUBY = 35, 314 | 315 | /** 316 | * @generated from enum value: LANGUAGE_RUST = 36; 317 | */ 318 | RUST = 36, 319 | 320 | /** 321 | * @generated from enum value: LANGUAGE_SASS = 37; 322 | */ 323 | SASS = 37, 324 | 325 | /** 326 | * @generated from enum value: LANGUAGE_SCALA = 38; 327 | */ 328 | SCALA = 38, 329 | 330 | /** 331 | * @generated from enum value: LANGUAGE_SCSS = 39; 332 | */ 333 | SCSS = 39, 334 | 335 | /** 336 | * @generated from enum value: LANGUAGE_SHELL = 40; 337 | */ 338 | SHELL = 40, 339 | 340 | /** 341 | * @generated from enum value: LANGUAGE_SQL = 41; 342 | */ 343 | SQL = 41, 344 | 345 | /** 346 | * @generated from enum value: LANGUAGE_STARLARK = 42; 347 | */ 348 | STARLARK = 42, 349 | 350 | /** 351 | * @generated from enum value: LANGUAGE_SWIFT = 43; 352 | */ 353 | SWIFT = 43, 354 | 355 | /** 356 | * @generated from enum value: LANGUAGE_TSX = 44; 357 | */ 358 | TSX = 44, 359 | 360 | /** 361 | * @generated from enum value: LANGUAGE_TYPESCRIPT = 45; 362 | */ 363 | TYPESCRIPT = 45, 364 | 365 | /** 366 | * @generated from enum value: LANGUAGE_VISUALBASIC = 46; 367 | */ 368 | VISUALBASIC = 46, 369 | 370 | /** 371 | * @generated from enum value: LANGUAGE_VUE = 47; 372 | */ 373 | VUE = 47, 374 | 375 | /** 376 | * @generated from enum value: LANGUAGE_XML = 48; 377 | */ 378 | XML = 48, 379 | 380 | /** 381 | * @generated from enum value: LANGUAGE_XSL = 49; 382 | */ 383 | XSL = 49, 384 | 385 | /** 386 | * @generated from enum value: LANGUAGE_YAML = 50; 387 | */ 388 | YAML = 50, 389 | 390 | /** 391 | * @generated from enum value: LANGUAGE_SVELTE = 51; 392 | */ 393 | SVELTE = 51, 394 | 395 | /** 396 | * @generated from enum value: LANGUAGE_TOML = 52; 397 | */ 398 | TOML = 52, 399 | 400 | /** 401 | * @generated from enum value: LANGUAGE_DART = 53; 402 | */ 403 | DART = 53, 404 | 405 | /** 406 | * @generated from enum value: LANGUAGE_RST = 54; 407 | */ 408 | RST = 54, 409 | 410 | /** 411 | * @generated from enum value: LANGUAGE_OCAML = 55; 412 | */ 413 | OCAML = 55, 414 | 415 | /** 416 | * @generated from enum value: LANGUAGE_CMAKE = 56; 417 | */ 418 | CMAKE = 56, 419 | 420 | /** 421 | * @generated from enum value: LANGUAGE_PASCAL = 57; 422 | */ 423 | PASCAL = 57, 424 | 425 | /** 426 | * @generated from enum value: LANGUAGE_ELIXIR = 58; 427 | */ 428 | ELIXIR = 58, 429 | 430 | /** 431 | * @generated from enum value: LANGUAGE_FSHARP = 59; 432 | */ 433 | FSHARP = 59, 434 | 435 | /** 436 | * @generated from enum value: LANGUAGE_LISP = 60; 437 | */ 438 | LISP = 60, 439 | 440 | /** 441 | * @generated from enum value: LANGUAGE_MATLAB = 61; 442 | */ 443 | MATLAB = 61, 444 | 445 | /** 446 | * @generated from enum value: LANGUAGE_POWERSHELL = 62; 447 | */ 448 | POWERSHELL = 62, 449 | 450 | /** 451 | * @generated from enum value: LANGUAGE_SOLIDITY = 63; 452 | */ 453 | SOLIDITY = 63, 454 | 455 | /** 456 | * @generated from enum value: LANGUAGE_ADA = 64; 457 | */ 458 | ADA = 64, 459 | 460 | /** 461 | * @generated from enum value: LANGUAGE_OCAML_INTERFACE = 65; 462 | */ 463 | OCAML_INTERFACE = 65 464 | } 465 | // Retrieve enum metadata with: proto3.getEnumType(Language) 466 | proto3.util.setEnumType(Language, 'exa.codeium_common_pb.Language', [ 467 | { no: 0, name: 'LANGUAGE_UNSPECIFIED' }, 468 | { no: 1, name: 'LANGUAGE_C' }, 469 | { no: 2, name: 'LANGUAGE_CLOJURE' }, 470 | { no: 3, name: 'LANGUAGE_COFFEESCRIPT' }, 471 | { no: 4, name: 'LANGUAGE_CPP' }, 472 | { no: 5, name: 'LANGUAGE_CSHARP' }, 473 | { no: 6, name: 'LANGUAGE_CSS' }, 474 | { no: 7, name: 'LANGUAGE_CUDACPP' }, 475 | { no: 8, name: 'LANGUAGE_DOCKERFILE' }, 476 | { no: 9, name: 'LANGUAGE_GO' }, 477 | { no: 10, name: 'LANGUAGE_GROOVY' }, 478 | { no: 11, name: 'LANGUAGE_HANDLEBARS' }, 479 | { no: 12, name: 'LANGUAGE_HASKELL' }, 480 | { no: 13, name: 'LANGUAGE_HCL' }, 481 | { no: 14, name: 'LANGUAGE_HTML' }, 482 | { no: 15, name: 'LANGUAGE_INI' }, 483 | { no: 16, name: 'LANGUAGE_JAVA' }, 484 | { no: 17, name: 'LANGUAGE_JAVASCRIPT' }, 485 | { no: 18, name: 'LANGUAGE_JSON' }, 486 | { no: 19, name: 'LANGUAGE_JULIA' }, 487 | { no: 20, name: 'LANGUAGE_KOTLIN' }, 488 | { no: 21, name: 'LANGUAGE_LATEX' }, 489 | { no: 22, name: 'LANGUAGE_LESS' }, 490 | { no: 23, name: 'LANGUAGE_LUA' }, 491 | { no: 24, name: 'LANGUAGE_MAKEFILE' }, 492 | { no: 25, name: 'LANGUAGE_MARKDOWN' }, 493 | { no: 26, name: 'LANGUAGE_OBJECTIVEC' }, 494 | { no: 27, name: 'LANGUAGE_OBJECTIVECPP' }, 495 | { no: 28, name: 'LANGUAGE_PERL' }, 496 | { no: 29, name: 'LANGUAGE_PHP' }, 497 | { no: 30, name: 'LANGUAGE_PLAINTEXT' }, 498 | { no: 31, name: 'LANGUAGE_PROTOBUF' }, 499 | { no: 32, name: 'LANGUAGE_PBTXT' }, 500 | { no: 33, name: 'LANGUAGE_PYTHON' }, 501 | { no: 34, name: 'LANGUAGE_R' }, 502 | { no: 35, name: 'LANGUAGE_RUBY' }, 503 | { no: 36, name: 'LANGUAGE_RUST' }, 504 | { no: 37, name: 'LANGUAGE_SASS' }, 505 | { no: 38, name: 'LANGUAGE_SCALA' }, 506 | { no: 39, name: 'LANGUAGE_SCSS' }, 507 | { no: 40, name: 'LANGUAGE_SHELL' }, 508 | { no: 41, name: 'LANGUAGE_SQL' }, 509 | { no: 42, name: 'LANGUAGE_STARLARK' }, 510 | { no: 43, name: 'LANGUAGE_SWIFT' }, 511 | { no: 44, name: 'LANGUAGE_TSX' }, 512 | { no: 45, name: 'LANGUAGE_TYPESCRIPT' }, 513 | { no: 46, name: 'LANGUAGE_VISUALBASIC' }, 514 | { no: 47, name: 'LANGUAGE_VUE' }, 515 | { no: 48, name: 'LANGUAGE_XML' }, 516 | { no: 49, name: 'LANGUAGE_XSL' }, 517 | { no: 50, name: 'LANGUAGE_YAML' }, 518 | { no: 51, name: 'LANGUAGE_SVELTE' }, 519 | { no: 52, name: 'LANGUAGE_TOML' }, 520 | { no: 53, name: 'LANGUAGE_DART' }, 521 | { no: 54, name: 'LANGUAGE_RST' }, 522 | { no: 55, name: 'LANGUAGE_OCAML' }, 523 | { no: 56, name: 'LANGUAGE_CMAKE' }, 524 | { no: 57, name: 'LANGUAGE_PASCAL' }, 525 | { no: 58, name: 'LANGUAGE_ELIXIR' }, 526 | { no: 59, name: 'LANGUAGE_FSHARP' }, 527 | { no: 60, name: 'LANGUAGE_LISP' }, 528 | { no: 61, name: 'LANGUAGE_MATLAB' }, 529 | { no: 62, name: 'LANGUAGE_POWERSHELL' }, 530 | { no: 63, name: 'LANGUAGE_SOLIDITY' }, 531 | { no: 64, name: 'LANGUAGE_ADA' }, 532 | { no: 65, name: 'LANGUAGE_OCAML_INTERFACE' } 533 | ]); 534 | 535 | /** 536 | * Next ID: 12, Previous field: entropy. 537 | * 538 | * @generated from message exa.codeium_common_pb.Completion 539 | */ 540 | export class Completion extends Message { 541 | /** 542 | * @generated from field: string completion_id = 1; 543 | */ 544 | completionId = ''; 545 | 546 | /** 547 | * @generated from field: string text = 2; 548 | */ 549 | text = ''; 550 | 551 | /** 552 | * @generated from field: string prefix = 3; 553 | */ 554 | prefix = ''; 555 | 556 | /** 557 | * @generated from field: string stop = 4; 558 | */ 559 | stop = ''; 560 | 561 | /** 562 | * @generated from field: double score = 5; 563 | */ 564 | score = 0; 565 | 566 | /** 567 | * @generated from field: repeated uint64 tokens = 6; 568 | */ 569 | tokens: bigint[] = []; 570 | 571 | /** 572 | * @generated from field: repeated string decoded_tokens = 7; 573 | */ 574 | decodedTokens: string[] = []; 575 | 576 | /** 577 | * @generated from field: repeated double probabilities = 8; 578 | */ 579 | probabilities: number[] = []; 580 | 581 | /** 582 | * @generated from field: repeated double adjusted_probabilities = 9; 583 | */ 584 | adjustedProbabilities: number[] = []; 585 | 586 | /** 587 | * @generated from field: uint64 generated_length = 10; 588 | */ 589 | generatedLength = protoInt64.zero; 590 | 591 | constructor(data?: PartialMessage) { 592 | super(); 593 | proto3.util.initPartial(data, this); 594 | } 595 | 596 | static readonly runtime: typeof proto3 = proto3; 597 | static readonly typeName = 'exa.codeium_common_pb.Completion'; 598 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 599 | { 600 | no: 1, 601 | name: 'completion_id', 602 | kind: 'scalar', 603 | T: 9 /* ScalarType.STRING */ 604 | }, 605 | { no: 2, name: 'text', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 606 | { no: 3, name: 'prefix', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 607 | { no: 4, name: 'stop', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 608 | { no: 5, name: 'score', kind: 'scalar', T: 1 /* ScalarType.DOUBLE */ }, 609 | { 610 | no: 6, 611 | name: 'tokens', 612 | kind: 'scalar', 613 | T: 4 /* ScalarType.UINT64 */, 614 | repeated: true 615 | }, 616 | { 617 | no: 7, 618 | name: 'decoded_tokens', 619 | kind: 'scalar', 620 | T: 9 /* ScalarType.STRING */, 621 | repeated: true 622 | }, 623 | { 624 | no: 8, 625 | name: 'probabilities', 626 | kind: 'scalar', 627 | T: 1 /* ScalarType.DOUBLE */, 628 | repeated: true 629 | }, 630 | { 631 | no: 9, 632 | name: 'adjusted_probabilities', 633 | kind: 'scalar', 634 | T: 1 /* ScalarType.DOUBLE */, 635 | repeated: true 636 | }, 637 | { 638 | no: 10, 639 | name: 'generated_length', 640 | kind: 'scalar', 641 | T: 4 /* ScalarType.UINT64 */ 642 | } 643 | ]); 644 | 645 | static fromBinary( 646 | bytes: Uint8Array, 647 | options?: Partial 648 | ): Completion { 649 | return new Completion().fromBinary(bytes, options); 650 | } 651 | 652 | static fromJson( 653 | jsonValue: JsonValue, 654 | options?: Partial 655 | ): Completion { 656 | return new Completion().fromJson(jsonValue, options); 657 | } 658 | 659 | static fromJsonString( 660 | jsonString: string, 661 | options?: Partial 662 | ): Completion { 663 | return new Completion().fromJsonString(jsonString, options); 664 | } 665 | 666 | static equals( 667 | a: Completion | PlainMessage | undefined, 668 | b: Completion | PlainMessage | undefined 669 | ): boolean { 670 | return proto3.util.equals(Completion, a, b); 671 | } 672 | } 673 | 674 | /** 675 | * Next ID: 15, Previous field: url. 676 | * 677 | * @generated from message exa.codeium_common_pb.Metadata 678 | */ 679 | export class Metadata extends Message { 680 | /** 681 | * @generated from field: string ide_name = 1; 682 | */ 683 | ideName = ''; 684 | 685 | /** 686 | * @generated from field: string ide_version = 7; 687 | */ 688 | ideVersion = ''; 689 | 690 | /** 691 | * @generated from field: string extension_name = 12; 692 | */ 693 | extensionName = ''; 694 | 695 | /** 696 | * @generated from field: string extension_version = 2; 697 | */ 698 | extensionVersion = ''; 699 | 700 | /** 701 | * @generated from field: string api_key = 3; 702 | */ 703 | apiKey = ''; 704 | 705 | /** 706 | * Regex derived from https://stackoverflow.com/a/48300605. 707 | * TODO(prem): Should this be mandatory? 708 | * 709 | * @generated from field: string locale = 4; 710 | */ 711 | locale = ''; 712 | 713 | /** 714 | * UID identifying a single session for the given user. 715 | * 716 | * @generated from field: string session_id = 10; 717 | */ 718 | sessionId = ''; 719 | 720 | /** 721 | * Used purely in language server to cancel in flight requests. 722 | * If request_id is 0, then the request is not cancelable. 723 | * This should be a strictly monotonically increasing number 724 | * for the duration of a session. 725 | * 726 | * @generated from field: uint64 request_id = 9; 727 | */ 728 | requestId = protoInt64.zero; 729 | 730 | /** 731 | * Browser-specific information. 732 | * 733 | * @generated from field: string user_agent = 13; 734 | */ 735 | userAgent = ''; 736 | 737 | /** 738 | * @generated from field: string url = 14; 739 | */ 740 | url = ''; 741 | 742 | /** 743 | * Authentication source information. 744 | * 745 | * @generated from field: exa.codeium_common_pb.AuthSource auth_source = 15; 746 | */ 747 | authSource = AuthSource.CODEIUM; 748 | 749 | constructor(data?: PartialMessage) { 750 | super(); 751 | proto3.util.initPartial(data, this); 752 | } 753 | 754 | static readonly runtime: typeof proto3 = proto3; 755 | static readonly typeName = 'exa.codeium_common_pb.Metadata'; 756 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 757 | { no: 1, name: 'ide_name', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 758 | { 759 | no: 7, 760 | name: 'ide_version', 761 | kind: 'scalar', 762 | T: 9 /* ScalarType.STRING */ 763 | }, 764 | { 765 | no: 12, 766 | name: 'extension_name', 767 | kind: 'scalar', 768 | T: 9 /* ScalarType.STRING */ 769 | }, 770 | { 771 | no: 2, 772 | name: 'extension_version', 773 | kind: 'scalar', 774 | T: 9 /* ScalarType.STRING */ 775 | }, 776 | { no: 3, name: 'api_key', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 777 | { no: 4, name: 'locale', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 778 | { 779 | no: 10, 780 | name: 'session_id', 781 | kind: 'scalar', 782 | T: 9 /* ScalarType.STRING */ 783 | }, 784 | { no: 9, name: 'request_id', kind: 'scalar', T: 4 /* ScalarType.UINT64 */ }, 785 | { 786 | no: 13, 787 | name: 'user_agent', 788 | kind: 'scalar', 789 | T: 9 /* ScalarType.STRING */ 790 | }, 791 | { no: 14, name: 'url', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 792 | { 793 | no: 15, 794 | name: 'auth_source', 795 | kind: 'enum', 796 | T: proto3.getEnumType(AuthSource) 797 | } 798 | ]); 799 | 800 | static fromBinary( 801 | bytes: Uint8Array, 802 | options?: Partial 803 | ): Metadata { 804 | return new Metadata().fromBinary(bytes, options); 805 | } 806 | 807 | static fromJson( 808 | jsonValue: JsonValue, 809 | options?: Partial 810 | ): Metadata { 811 | return new Metadata().fromJson(jsonValue, options); 812 | } 813 | 814 | static fromJsonString( 815 | jsonString: string, 816 | options?: Partial 817 | ): Metadata { 818 | return new Metadata().fromJsonString(jsonString, options); 819 | } 820 | 821 | static equals( 822 | a: Metadata | PlainMessage | undefined, 823 | b: Metadata | PlainMessage | undefined 824 | ): boolean { 825 | return proto3.util.equals(Metadata, a, b); 826 | } 827 | } 828 | 829 | /** 830 | * Next ID: 3, Previous field: insert_spaces. 831 | * 832 | * @generated from message exa.codeium_common_pb.EditorOptions 833 | */ 834 | export class EditorOptions extends Message { 835 | /** 836 | * @generated from field: uint64 tab_size = 1; 837 | */ 838 | tabSize = protoInt64.zero; 839 | 840 | /** 841 | * @generated from field: bool insert_spaces = 2; 842 | */ 843 | insertSpaces = false; 844 | 845 | constructor(data?: PartialMessage) { 846 | super(); 847 | proto3.util.initPartial(data, this); 848 | } 849 | 850 | static readonly runtime: typeof proto3 = proto3; 851 | static readonly typeName = 'exa.codeium_common_pb.EditorOptions'; 852 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 853 | { no: 1, name: 'tab_size', kind: 'scalar', T: 4 /* ScalarType.UINT64 */ }, 854 | { no: 2, name: 'insert_spaces', kind: 'scalar', T: 8 /* ScalarType.BOOL */ } 855 | ]); 856 | 857 | static fromBinary( 858 | bytes: Uint8Array, 859 | options?: Partial 860 | ): EditorOptions { 861 | return new EditorOptions().fromBinary(bytes, options); 862 | } 863 | 864 | static fromJson( 865 | jsonValue: JsonValue, 866 | options?: Partial 867 | ): EditorOptions { 868 | return new EditorOptions().fromJson(jsonValue, options); 869 | } 870 | 871 | static fromJsonString( 872 | jsonString: string, 873 | options?: Partial 874 | ): EditorOptions { 875 | return new EditorOptions().fromJsonString(jsonString, options); 876 | } 877 | 878 | static equals( 879 | a: EditorOptions | PlainMessage | undefined, 880 | b: EditorOptions | PlainMessage | undefined 881 | ): boolean { 882 | return proto3.util.equals(EditorOptions, a, b); 883 | } 884 | } 885 | 886 | /** 887 | * @generated from message exa.codeium_common_pb.Event 888 | */ 889 | export class Event extends Message { 890 | /** 891 | * @generated from field: exa.codeium_common_pb.EventType event_type = 1; 892 | */ 893 | eventType = EventType.UNSPECIFIED; 894 | 895 | /** 896 | * @generated from field: string event_json = 2; 897 | */ 898 | eventJson = ''; 899 | 900 | /** 901 | * @generated from field: int64 timestamp_unix_ms = 3; 902 | */ 903 | timestampUnixMs = protoInt64.zero; 904 | 905 | constructor(data?: PartialMessage) { 906 | super(); 907 | proto3.util.initPartial(data, this); 908 | } 909 | 910 | static readonly runtime: typeof proto3 = proto3; 911 | static readonly typeName = 'exa.codeium_common_pb.Event'; 912 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 913 | { 914 | no: 1, 915 | name: 'event_type', 916 | kind: 'enum', 917 | T: proto3.getEnumType(EventType) 918 | }, 919 | { no: 2, name: 'event_json', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 920 | { 921 | no: 3, 922 | name: 'timestamp_unix_ms', 923 | kind: 'scalar', 924 | T: 3 /* ScalarType.INT64 */ 925 | } 926 | ]); 927 | 928 | static fromBinary( 929 | bytes: Uint8Array, 930 | options?: Partial 931 | ): Event { 932 | return new Event().fromBinary(bytes, options); 933 | } 934 | 935 | static fromJson( 936 | jsonValue: JsonValue, 937 | options?: Partial 938 | ): Event { 939 | return new Event().fromJson(jsonValue, options); 940 | } 941 | 942 | static fromJsonString( 943 | jsonString: string, 944 | options?: Partial 945 | ): Event { 946 | return new Event().fromJsonString(jsonString, options); 947 | } 948 | 949 | static equals( 950 | a: Event | PlainMessage | undefined, 951 | b: Event | PlainMessage | undefined 952 | ): boolean { 953 | return proto3.util.equals(Event, a, b); 954 | } 955 | } 956 | -------------------------------------------------------------------------------- /src/api/proto/exa/language_server_pb/language_server_connect.ts: -------------------------------------------------------------------------------- 1 | // Copyright Exafunction, Inc. 2 | 3 | // @generated by protoc-gen-connect-es v1.1.3 with parameter "target=ts" 4 | // @generated from file exa/language_server_pb/language_server.proto (package exa.language_server_pb, syntax proto3) 5 | /* eslint-disable */ 6 | // @ts-nocheck 7 | 8 | import { 9 | AcceptCompletionRequest, 10 | AcceptCompletionResponse, 11 | GetAuthTokenRequest, 12 | GetAuthTokenResponse, 13 | GetCompletionsRequest, 14 | GetCompletionsResponse 15 | } from './language_server_pb'; 16 | import { MethodKind } from '@bufbuild/protobuf'; 17 | 18 | /** 19 | * @generated from service exa.language_server_pb.LanguageServerService 20 | */ 21 | export const LanguageServerService = { 22 | typeName: 'exa.language_server_pb.LanguageServerService', 23 | methods: { 24 | /** 25 | * @generated from rpc exa.language_server_pb.LanguageServerService.GetCompletions 26 | */ 27 | getCompletions: { 28 | name: 'GetCompletions', 29 | I: GetCompletionsRequest, 30 | O: GetCompletionsResponse, 31 | kind: MethodKind.Unary 32 | }, 33 | /** 34 | * @generated from rpc exa.language_server_pb.LanguageServerService.AcceptCompletion 35 | */ 36 | acceptCompletion: { 37 | name: 'AcceptCompletion', 38 | I: AcceptCompletionRequest, 39 | O: AcceptCompletionResponse, 40 | kind: MethodKind.Unary 41 | }, 42 | /** 43 | * @generated from rpc exa.language_server_pb.LanguageServerService.GetAuthToken 44 | */ 45 | getAuthToken: { 46 | name: 'GetAuthToken', 47 | I: GetAuthTokenRequest, 48 | O: GetAuthTokenResponse, 49 | kind: MethodKind.Unary 50 | } 51 | } 52 | } as const; 53 | -------------------------------------------------------------------------------- /src/api/proto/exa/language_server_pb/language_server_pb.ts: -------------------------------------------------------------------------------- 1 | // Copyright Exafunction, Inc. 2 | 3 | // @generated by protoc-gen-es v1.4.2 with parameter "target=ts" 4 | // @generated from file exa/language_server_pb/language_server.proto (package exa.language_server_pb, syntax proto3) 5 | /* eslint-disable */ 6 | // @ts-nocheck 7 | 8 | import type { 9 | BinaryReadOptions, 10 | FieldList, 11 | JsonReadOptions, 12 | JsonValue, 13 | PartialMessage, 14 | PlainMessage 15 | } from '@bufbuild/protobuf'; 16 | import { Message, proto3, protoInt64 } from '@bufbuild/protobuf'; 17 | import { 18 | Completion, 19 | CompletionSource, 20 | EditorOptions, 21 | ExperimentKey, 22 | Language, 23 | Metadata 24 | } from '../codeium_common_pb/codeium_common_pb'; 25 | 26 | /** 27 | * @generated from enum exa.language_server_pb.CodeiumState 28 | */ 29 | export enum CodeiumState { 30 | /** 31 | * @generated from enum value: CODEIUM_STATE_UNSPECIFIED = 0; 32 | */ 33 | UNSPECIFIED = 0, 34 | 35 | /** 36 | * @generated from enum value: CODEIUM_STATE_INACTIVE = 1; 37 | */ 38 | INACTIVE = 1, 39 | 40 | /** 41 | * @generated from enum value: CODEIUM_STATE_PROCESSING = 2; 42 | */ 43 | PROCESSING = 2, 44 | 45 | /** 46 | * @generated from enum value: CODEIUM_STATE_SUCCESS = 3; 47 | */ 48 | SUCCESS = 3, 49 | 50 | /** 51 | * @generated from enum value: CODEIUM_STATE_WARNING = 4; 52 | */ 53 | WARNING = 4, 54 | 55 | /** 56 | * @generated from enum value: CODEIUM_STATE_ERROR = 5; 57 | */ 58 | ERROR = 5 59 | } 60 | // Retrieve enum metadata with: proto3.getEnumType(CodeiumState) 61 | proto3.util.setEnumType(CodeiumState, 'exa.language_server_pb.CodeiumState', [ 62 | { no: 0, name: 'CODEIUM_STATE_UNSPECIFIED' }, 63 | { no: 1, name: 'CODEIUM_STATE_INACTIVE' }, 64 | { no: 2, name: 'CODEIUM_STATE_PROCESSING' }, 65 | { no: 3, name: 'CODEIUM_STATE_SUCCESS' }, 66 | { no: 4, name: 'CODEIUM_STATE_WARNING' }, 67 | { no: 5, name: 'CODEIUM_STATE_ERROR' } 68 | ]); 69 | 70 | /** 71 | * @generated from enum exa.language_server_pb.LineType 72 | */ 73 | export enum LineType { 74 | /** 75 | * @generated from enum value: LINE_TYPE_UNSPECIFIED = 0; 76 | */ 77 | UNSPECIFIED = 0, 78 | 79 | /** 80 | * @generated from enum value: LINE_TYPE_SINGLE = 1; 81 | */ 82 | SINGLE = 1, 83 | 84 | /** 85 | * @generated from enum value: LINE_TYPE_MULTI = 2; 86 | */ 87 | MULTI = 2 88 | } 89 | // Retrieve enum metadata with: proto3.getEnumType(LineType) 90 | proto3.util.setEnumType(LineType, 'exa.language_server_pb.LineType', [ 91 | { no: 0, name: 'LINE_TYPE_UNSPECIFIED' }, 92 | { no: 1, name: 'LINE_TYPE_SINGLE' }, 93 | { no: 2, name: 'LINE_TYPE_MULTI' } 94 | ]); 95 | 96 | /** 97 | * @generated from enum exa.language_server_pb.CompletionPartType 98 | */ 99 | export enum CompletionPartType { 100 | /** 101 | * @generated from enum value: COMPLETION_PART_TYPE_UNSPECIFIED = 0; 102 | */ 103 | UNSPECIFIED = 0, 104 | 105 | /** 106 | * Single-line completion parts that appear within an existing line of text. 107 | * 108 | * @generated from enum value: COMPLETION_PART_TYPE_INLINE = 1; 109 | */ 110 | INLINE = 1, 111 | 112 | /** 113 | * Possibly multi-line completion parts that appear below an existing line of text. 114 | * 115 | * @generated from enum value: COMPLETION_PART_TYPE_BLOCK = 2; 116 | */ 117 | BLOCK = 2, 118 | 119 | /** 120 | * Like COMPLETION_PART_TYPE_INLINE, but overwrites the existing text. 121 | * 122 | * @generated from enum value: COMPLETION_PART_TYPE_INLINE_MASK = 3; 123 | */ 124 | INLINE_MASK = 3 125 | } 126 | // Retrieve enum metadata with: proto3.getEnumType(CompletionPartType) 127 | proto3.util.setEnumType( 128 | CompletionPartType, 129 | 'exa.language_server_pb.CompletionPartType', 130 | [ 131 | { no: 0, name: 'COMPLETION_PART_TYPE_UNSPECIFIED' }, 132 | { no: 1, name: 'COMPLETION_PART_TYPE_INLINE' }, 133 | { no: 2, name: 'COMPLETION_PART_TYPE_BLOCK' }, 134 | { no: 3, name: 'COMPLETION_PART_TYPE_INLINE_MASK' } 135 | ] 136 | ); 137 | 138 | /** 139 | * @generated from message exa.language_server_pb.MultilineConfig 140 | */ 141 | export class MultilineConfig extends Message { 142 | /** 143 | * Multiline model threshold. 0-1, higher = more single line, lower = more multiline, 144 | * 0.0 = only_multiline, default is 0.5 145 | * 146 | * @generated from field: float threshold = 1; 147 | */ 148 | threshold = 0; 149 | 150 | constructor(data?: PartialMessage) { 151 | super(); 152 | proto3.util.initPartial(data, this); 153 | } 154 | 155 | static readonly runtime: typeof proto3 = proto3; 156 | static readonly typeName = 'exa.language_server_pb.MultilineConfig'; 157 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 158 | { no: 1, name: 'threshold', kind: 'scalar', T: 2 /* ScalarType.FLOAT */ } 159 | ]); 160 | 161 | static fromBinary( 162 | bytes: Uint8Array, 163 | options?: Partial 164 | ): MultilineConfig { 165 | return new MultilineConfig().fromBinary(bytes, options); 166 | } 167 | 168 | static fromJson( 169 | jsonValue: JsonValue, 170 | options?: Partial 171 | ): MultilineConfig { 172 | return new MultilineConfig().fromJson(jsonValue, options); 173 | } 174 | 175 | static fromJsonString( 176 | jsonString: string, 177 | options?: Partial 178 | ): MultilineConfig { 179 | return new MultilineConfig().fromJsonString(jsonString, options); 180 | } 181 | 182 | static equals( 183 | a: MultilineConfig | PlainMessage | undefined, 184 | b: MultilineConfig | PlainMessage | undefined 185 | ): boolean { 186 | return proto3.util.equals(MultilineConfig, a, b); 187 | } 188 | } 189 | 190 | /** 191 | * Next ID: 9, Previous field: disable_cache. 192 | * 193 | * @generated from message exa.language_server_pb.GetCompletionsRequest 194 | */ 195 | export class GetCompletionsRequest extends Message { 196 | /** 197 | * @generated from field: exa.codeium_common_pb.Metadata metadata = 1; 198 | */ 199 | metadata?: Metadata; 200 | 201 | /** 202 | * @generated from field: exa.language_server_pb.Document document = 2; 203 | */ 204 | document?: Document; 205 | 206 | /** 207 | * @generated from field: exa.codeium_common_pb.EditorOptions editor_options = 3; 208 | */ 209 | editorOptions?: EditorOptions; 210 | 211 | /** 212 | * @generated from field: repeated exa.language_server_pb.Document other_documents = 5; 213 | */ 214 | otherDocuments: Document[] = []; 215 | 216 | /** 217 | * @generated from field: exa.language_server_pb.ExperimentConfig experiment_config = 7; 218 | */ 219 | experimentConfig?: ExperimentConfig; 220 | 221 | /** 222 | * @generated from field: string model_name = 10; 223 | */ 224 | modelName = ''; 225 | 226 | /** 227 | * @generated from field: exa.language_server_pb.MultilineConfig multiline_config = 13; 228 | */ 229 | multilineConfig?: MultilineConfig; 230 | 231 | constructor(data?: PartialMessage) { 232 | super(); 233 | proto3.util.initPartial(data, this); 234 | } 235 | 236 | static readonly runtime: typeof proto3 = proto3; 237 | static readonly typeName = 'exa.language_server_pb.GetCompletionsRequest'; 238 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 239 | { no: 1, name: 'metadata', kind: 'message', T: Metadata }, 240 | { no: 2, name: 'document', kind: 'message', T: Document }, 241 | { no: 3, name: 'editor_options', kind: 'message', T: EditorOptions }, 242 | { 243 | no: 5, 244 | name: 'other_documents', 245 | kind: 'message', 246 | T: Document, 247 | repeated: true 248 | }, 249 | { no: 7, name: 'experiment_config', kind: 'message', T: ExperimentConfig }, 250 | { 251 | no: 10, 252 | name: 'model_name', 253 | kind: 'scalar', 254 | T: 9 /* ScalarType.STRING */ 255 | }, 256 | { no: 13, name: 'multiline_config', kind: 'message', T: MultilineConfig } 257 | ]); 258 | 259 | static fromBinary( 260 | bytes: Uint8Array, 261 | options?: Partial 262 | ): GetCompletionsRequest { 263 | return new GetCompletionsRequest().fromBinary(bytes, options); 264 | } 265 | 266 | static fromJson( 267 | jsonValue: JsonValue, 268 | options?: Partial 269 | ): GetCompletionsRequest { 270 | return new GetCompletionsRequest().fromJson(jsonValue, options); 271 | } 272 | 273 | static fromJsonString( 274 | jsonString: string, 275 | options?: Partial 276 | ): GetCompletionsRequest { 277 | return new GetCompletionsRequest().fromJsonString(jsonString, options); 278 | } 279 | 280 | static equals( 281 | a: GetCompletionsRequest | PlainMessage | undefined, 282 | b: GetCompletionsRequest | PlainMessage | undefined 283 | ): boolean { 284 | return proto3.util.equals(GetCompletionsRequest, a, b); 285 | } 286 | } 287 | 288 | /** 289 | * Next ID: 5, Previous field: latency_info. 290 | * 291 | * @generated from message exa.language_server_pb.GetCompletionsResponse 292 | */ 293 | export class GetCompletionsResponse extends Message { 294 | /** 295 | * @generated from field: exa.language_server_pb.State state = 1; 296 | */ 297 | state?: State; 298 | 299 | /** 300 | * @generated from field: repeated exa.language_server_pb.CompletionItem completion_items = 2; 301 | */ 302 | completionItems: CompletionItem[] = []; 303 | 304 | constructor(data?: PartialMessage) { 305 | super(); 306 | proto3.util.initPartial(data, this); 307 | } 308 | 309 | static readonly runtime: typeof proto3 = proto3; 310 | static readonly typeName = 'exa.language_server_pb.GetCompletionsResponse'; 311 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 312 | { no: 1, name: 'state', kind: 'message', T: State }, 313 | { 314 | no: 2, 315 | name: 'completion_items', 316 | kind: 'message', 317 | T: CompletionItem, 318 | repeated: true 319 | } 320 | ]); 321 | 322 | static fromBinary( 323 | bytes: Uint8Array, 324 | options?: Partial 325 | ): GetCompletionsResponse { 326 | return new GetCompletionsResponse().fromBinary(bytes, options); 327 | } 328 | 329 | static fromJson( 330 | jsonValue: JsonValue, 331 | options?: Partial 332 | ): GetCompletionsResponse { 333 | return new GetCompletionsResponse().fromJson(jsonValue, options); 334 | } 335 | 336 | static fromJsonString( 337 | jsonString: string, 338 | options?: Partial 339 | ): GetCompletionsResponse { 340 | return new GetCompletionsResponse().fromJsonString(jsonString, options); 341 | } 342 | 343 | static equals( 344 | a: 345 | | GetCompletionsResponse 346 | | PlainMessage 347 | | undefined, 348 | b: GetCompletionsResponse | PlainMessage | undefined 349 | ): boolean { 350 | return proto3.util.equals(GetCompletionsResponse, a, b); 351 | } 352 | } 353 | 354 | /** 355 | * Next ID: 3, Previous field: completion_id. 356 | * 357 | * @generated from message exa.language_server_pb.AcceptCompletionRequest 358 | */ 359 | export class AcceptCompletionRequest extends Message { 360 | /** 361 | * @generated from field: exa.codeium_common_pb.Metadata metadata = 1; 362 | */ 363 | metadata?: Metadata; 364 | 365 | /** 366 | * @generated from field: string completion_id = 2; 367 | */ 368 | completionId = ''; 369 | 370 | constructor(data?: PartialMessage) { 371 | super(); 372 | proto3.util.initPartial(data, this); 373 | } 374 | 375 | static readonly runtime: typeof proto3 = proto3; 376 | static readonly typeName = 'exa.language_server_pb.AcceptCompletionRequest'; 377 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 378 | { no: 1, name: 'metadata', kind: 'message', T: Metadata }, 379 | { 380 | no: 2, 381 | name: 'completion_id', 382 | kind: 'scalar', 383 | T: 9 /* ScalarType.STRING */ 384 | } 385 | ]); 386 | 387 | static fromBinary( 388 | bytes: Uint8Array, 389 | options?: Partial 390 | ): AcceptCompletionRequest { 391 | return new AcceptCompletionRequest().fromBinary(bytes, options); 392 | } 393 | 394 | static fromJson( 395 | jsonValue: JsonValue, 396 | options?: Partial 397 | ): AcceptCompletionRequest { 398 | return new AcceptCompletionRequest().fromJson(jsonValue, options); 399 | } 400 | 401 | static fromJsonString( 402 | jsonString: string, 403 | options?: Partial 404 | ): AcceptCompletionRequest { 405 | return new AcceptCompletionRequest().fromJsonString(jsonString, options); 406 | } 407 | 408 | static equals( 409 | a: 410 | | AcceptCompletionRequest 411 | | PlainMessage 412 | | undefined, 413 | b: 414 | | AcceptCompletionRequest 415 | | PlainMessage 416 | | undefined 417 | ): boolean { 418 | return proto3.util.equals(AcceptCompletionRequest, a, b); 419 | } 420 | } 421 | 422 | /** 423 | * Next ID: 1, Previous field: N/A. 424 | * 425 | * @generated from message exa.language_server_pb.AcceptCompletionResponse 426 | */ 427 | export class AcceptCompletionResponse extends Message { 428 | constructor(data?: PartialMessage) { 429 | super(); 430 | proto3.util.initPartial(data, this); 431 | } 432 | 433 | static readonly runtime: typeof proto3 = proto3; 434 | static readonly typeName = 'exa.language_server_pb.AcceptCompletionResponse'; 435 | static readonly fields: FieldList = proto3.util.newFieldList(() => []); 436 | 437 | static fromBinary( 438 | bytes: Uint8Array, 439 | options?: Partial 440 | ): AcceptCompletionResponse { 441 | return new AcceptCompletionResponse().fromBinary(bytes, options); 442 | } 443 | 444 | static fromJson( 445 | jsonValue: JsonValue, 446 | options?: Partial 447 | ): AcceptCompletionResponse { 448 | return new AcceptCompletionResponse().fromJson(jsonValue, options); 449 | } 450 | 451 | static fromJsonString( 452 | jsonString: string, 453 | options?: Partial 454 | ): AcceptCompletionResponse { 455 | return new AcceptCompletionResponse().fromJsonString(jsonString, options); 456 | } 457 | 458 | static equals( 459 | a: 460 | | AcceptCompletionResponse 461 | | PlainMessage 462 | | undefined, 463 | b: 464 | | AcceptCompletionResponse 465 | | PlainMessage 466 | | undefined 467 | ): boolean { 468 | return proto3.util.equals(AcceptCompletionResponse, a, b); 469 | } 470 | } 471 | 472 | /** 473 | * Next ID: 1, Previous field: N/A. 474 | * 475 | * @generated from message exa.language_server_pb.GetAuthTokenRequest 476 | */ 477 | export class GetAuthTokenRequest extends Message { 478 | constructor(data?: PartialMessage) { 479 | super(); 480 | proto3.util.initPartial(data, this); 481 | } 482 | 483 | static readonly runtime: typeof proto3 = proto3; 484 | static readonly typeName = 'exa.language_server_pb.GetAuthTokenRequest'; 485 | static readonly fields: FieldList = proto3.util.newFieldList(() => []); 486 | 487 | static fromBinary( 488 | bytes: Uint8Array, 489 | options?: Partial 490 | ): GetAuthTokenRequest { 491 | return new GetAuthTokenRequest().fromBinary(bytes, options); 492 | } 493 | 494 | static fromJson( 495 | jsonValue: JsonValue, 496 | options?: Partial 497 | ): GetAuthTokenRequest { 498 | return new GetAuthTokenRequest().fromJson(jsonValue, options); 499 | } 500 | 501 | static fromJsonString( 502 | jsonString: string, 503 | options?: Partial 504 | ): GetAuthTokenRequest { 505 | return new GetAuthTokenRequest().fromJsonString(jsonString, options); 506 | } 507 | 508 | static equals( 509 | a: GetAuthTokenRequest | PlainMessage | undefined, 510 | b: GetAuthTokenRequest | PlainMessage | undefined 511 | ): boolean { 512 | return proto3.util.equals(GetAuthTokenRequest, a, b); 513 | } 514 | } 515 | 516 | /** 517 | * Next ID: 3, Previous field: uuid. 518 | * 519 | * @generated from message exa.language_server_pb.GetAuthTokenResponse 520 | */ 521 | export class GetAuthTokenResponse extends Message { 522 | /** 523 | * @generated from field: string auth_token = 1; 524 | */ 525 | authToken = ''; 526 | 527 | /** 528 | * @generated from field: string uuid = 2; 529 | */ 530 | uuid = ''; 531 | 532 | constructor(data?: PartialMessage) { 533 | super(); 534 | proto3.util.initPartial(data, this); 535 | } 536 | 537 | static readonly runtime: typeof proto3 = proto3; 538 | static readonly typeName = 'exa.language_server_pb.GetAuthTokenResponse'; 539 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 540 | { no: 1, name: 'auth_token', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 541 | { no: 2, name: 'uuid', kind: 'scalar', T: 9 /* ScalarType.STRING */ } 542 | ]); 543 | 544 | static fromBinary( 545 | bytes: Uint8Array, 546 | options?: Partial 547 | ): GetAuthTokenResponse { 548 | return new GetAuthTokenResponse().fromBinary(bytes, options); 549 | } 550 | 551 | static fromJson( 552 | jsonValue: JsonValue, 553 | options?: Partial 554 | ): GetAuthTokenResponse { 555 | return new GetAuthTokenResponse().fromJson(jsonValue, options); 556 | } 557 | 558 | static fromJsonString( 559 | jsonString: string, 560 | options?: Partial 561 | ): GetAuthTokenResponse { 562 | return new GetAuthTokenResponse().fromJsonString(jsonString, options); 563 | } 564 | 565 | static equals( 566 | a: GetAuthTokenResponse | PlainMessage | undefined, 567 | b: GetAuthTokenResponse | PlainMessage | undefined 568 | ): boolean { 569 | return proto3.util.equals(GetAuthTokenResponse, a, b); 570 | } 571 | } 572 | 573 | /** 574 | * @generated from message exa.language_server_pb.DocumentPosition 575 | */ 576 | export class DocumentPosition extends Message { 577 | /** 578 | * 0-indexed. Measured in UTF-8 bytes. 579 | * 580 | * @generated from field: uint64 row = 1; 581 | */ 582 | row = protoInt64.zero; 583 | 584 | /** 585 | * 0-indexed. Measured in UTF-8 bytes. 586 | * 587 | * @generated from field: uint64 col = 2; 588 | */ 589 | col = protoInt64.zero; 590 | 591 | constructor(data?: PartialMessage) { 592 | super(); 593 | proto3.util.initPartial(data, this); 594 | } 595 | 596 | static readonly runtime: typeof proto3 = proto3; 597 | static readonly typeName = 'exa.language_server_pb.DocumentPosition'; 598 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 599 | { no: 1, name: 'row', kind: 'scalar', T: 4 /* ScalarType.UINT64 */ }, 600 | { no: 2, name: 'col', kind: 'scalar', T: 4 /* ScalarType.UINT64 */ } 601 | ]); 602 | 603 | static fromBinary( 604 | bytes: Uint8Array, 605 | options?: Partial 606 | ): DocumentPosition { 607 | return new DocumentPosition().fromBinary(bytes, options); 608 | } 609 | 610 | static fromJson( 611 | jsonValue: JsonValue, 612 | options?: Partial 613 | ): DocumentPosition { 614 | return new DocumentPosition().fromJson(jsonValue, options); 615 | } 616 | 617 | static fromJsonString( 618 | jsonString: string, 619 | options?: Partial 620 | ): DocumentPosition { 621 | return new DocumentPosition().fromJsonString(jsonString, options); 622 | } 623 | 624 | static equals( 625 | a: DocumentPosition | PlainMessage | undefined, 626 | b: DocumentPosition | PlainMessage | undefined 627 | ): boolean { 628 | return proto3.util.equals(DocumentPosition, a, b); 629 | } 630 | } 631 | 632 | /** 633 | * Next ID: 9, Previous field: cursor_position. 634 | * 635 | * @generated from message exa.language_server_pb.Document 636 | */ 637 | export class Document extends Message { 638 | /** 639 | * @generated from field: string absolute_path = 1; 640 | */ 641 | absolutePath = ''; 642 | 643 | /** 644 | * Path relative to the root of the workspace. 645 | * 646 | * @generated from field: string relative_path = 2; 647 | */ 648 | relativePath = ''; 649 | 650 | /** 651 | * @generated from field: string text = 3; 652 | */ 653 | text = ''; 654 | 655 | /** 656 | * Language ID provided by the editor. 657 | * 658 | * @generated from field: string editor_language = 4; 659 | */ 660 | editorLanguage = ''; 661 | 662 | /** 663 | * Language enum standardized across editors. 664 | * 665 | * @generated from field: exa.codeium_common_pb.Language language = 5; 666 | */ 667 | language = Language.UNSPECIFIED; 668 | 669 | /** 670 | * Measured in number of UTF-8 bytes. 671 | * 672 | * @generated from field: uint64 cursor_offset = 6; 673 | */ 674 | cursorOffset = protoInt64.zero; 675 | 676 | /** 677 | * May be present instead of cursor_offset. 678 | * 679 | * @generated from field: exa.language_server_pb.DocumentPosition cursor_position = 8; 680 | */ 681 | cursorPosition?: DocumentPosition; 682 | 683 | /** 684 | * \n or \r\n, if known. 685 | * 686 | * @generated from field: string line_ending = 7; 687 | */ 688 | lineEnding = ''; 689 | 690 | constructor(data?: PartialMessage) { 691 | super(); 692 | proto3.util.initPartial(data, this); 693 | } 694 | 695 | static readonly runtime: typeof proto3 = proto3; 696 | static readonly typeName = 'exa.language_server_pb.Document'; 697 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 698 | { 699 | no: 1, 700 | name: 'absolute_path', 701 | kind: 'scalar', 702 | T: 9 /* ScalarType.STRING */ 703 | }, 704 | { 705 | no: 2, 706 | name: 'relative_path', 707 | kind: 'scalar', 708 | T: 9 /* ScalarType.STRING */ 709 | }, 710 | { no: 3, name: 'text', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 711 | { 712 | no: 4, 713 | name: 'editor_language', 714 | kind: 'scalar', 715 | T: 9 /* ScalarType.STRING */ 716 | }, 717 | { no: 5, name: 'language', kind: 'enum', T: proto3.getEnumType(Language) }, 718 | { 719 | no: 6, 720 | name: 'cursor_offset', 721 | kind: 'scalar', 722 | T: 4 /* ScalarType.UINT64 */ 723 | }, 724 | { no: 8, name: 'cursor_position', kind: 'message', T: DocumentPosition }, 725 | { no: 7, name: 'line_ending', kind: 'scalar', T: 9 /* ScalarType.STRING */ } 726 | ]); 727 | 728 | static fromBinary( 729 | bytes: Uint8Array, 730 | options?: Partial 731 | ): Document { 732 | return new Document().fromBinary(bytes, options); 733 | } 734 | 735 | static fromJson( 736 | jsonValue: JsonValue, 737 | options?: Partial 738 | ): Document { 739 | return new Document().fromJson(jsonValue, options); 740 | } 741 | 742 | static fromJsonString( 743 | jsonString: string, 744 | options?: Partial 745 | ): Document { 746 | return new Document().fromJsonString(jsonString, options); 747 | } 748 | 749 | static equals( 750 | a: Document | PlainMessage | undefined, 751 | b: Document | PlainMessage | undefined 752 | ): boolean { 753 | return proto3.util.equals(Document, a, b); 754 | } 755 | } 756 | 757 | /** 758 | * @generated from message exa.language_server_pb.ExperimentConfig 759 | */ 760 | export class ExperimentConfig extends Message { 761 | /** 762 | * @generated from field: repeated exa.codeium_common_pb.ExperimentKey force_enable_experiments = 1; 763 | */ 764 | forceEnableExperiments: ExperimentKey[] = []; 765 | 766 | constructor(data?: PartialMessage) { 767 | super(); 768 | proto3.util.initPartial(data, this); 769 | } 770 | 771 | static readonly runtime: typeof proto3 = proto3; 772 | static readonly typeName = 'exa.language_server_pb.ExperimentConfig'; 773 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 774 | { 775 | no: 1, 776 | name: 'force_enable_experiments', 777 | kind: 'enum', 778 | T: proto3.getEnumType(ExperimentKey), 779 | repeated: true 780 | } 781 | ]); 782 | 783 | static fromBinary( 784 | bytes: Uint8Array, 785 | options?: Partial 786 | ): ExperimentConfig { 787 | return new ExperimentConfig().fromBinary(bytes, options); 788 | } 789 | 790 | static fromJson( 791 | jsonValue: JsonValue, 792 | options?: Partial 793 | ): ExperimentConfig { 794 | return new ExperimentConfig().fromJson(jsonValue, options); 795 | } 796 | 797 | static fromJsonString( 798 | jsonString: string, 799 | options?: Partial 800 | ): ExperimentConfig { 801 | return new ExperimentConfig().fromJsonString(jsonString, options); 802 | } 803 | 804 | static equals( 805 | a: ExperimentConfig | PlainMessage | undefined, 806 | b: ExperimentConfig | PlainMessage | undefined 807 | ): boolean { 808 | return proto3.util.equals(ExperimentConfig, a, b); 809 | } 810 | } 811 | 812 | /** 813 | * Next ID: 3, Previous field: message. 814 | * 815 | * @generated from message exa.language_server_pb.State 816 | */ 817 | export class State extends Message { 818 | /** 819 | * @generated from field: exa.language_server_pb.CodeiumState state = 1; 820 | */ 821 | state = CodeiumState.UNSPECIFIED; 822 | 823 | /** 824 | * @generated from field: string message = 2; 825 | */ 826 | message = ''; 827 | 828 | constructor(data?: PartialMessage) { 829 | super(); 830 | proto3.util.initPartial(data, this); 831 | } 832 | 833 | static readonly runtime: typeof proto3 = proto3; 834 | static readonly typeName = 'exa.language_server_pb.State'; 835 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 836 | { no: 1, name: 'state', kind: 'enum', T: proto3.getEnumType(CodeiumState) }, 837 | { no: 2, name: 'message', kind: 'scalar', T: 9 /* ScalarType.STRING */ } 838 | ]); 839 | 840 | static fromBinary( 841 | bytes: Uint8Array, 842 | options?: Partial 843 | ): State { 844 | return new State().fromBinary(bytes, options); 845 | } 846 | 847 | static fromJson( 848 | jsonValue: JsonValue, 849 | options?: Partial 850 | ): State { 851 | return new State().fromJson(jsonValue, options); 852 | } 853 | 854 | static fromJsonString( 855 | jsonString: string, 856 | options?: Partial 857 | ): State { 858 | return new State().fromJsonString(jsonString, options); 859 | } 860 | 861 | static equals( 862 | a: State | PlainMessage | undefined, 863 | b: State | PlainMessage | undefined 864 | ): boolean { 865 | return proto3.util.equals(State, a, b); 866 | } 867 | } 868 | 869 | /** 870 | * Next ID: 5, Previous field: end_position. 871 | * 872 | * @generated from message exa.language_server_pb.Range 873 | */ 874 | export class Range extends Message { 875 | /** 876 | * @generated from field: uint64 start_offset = 1; 877 | */ 878 | startOffset = protoInt64.zero; 879 | 880 | /** 881 | * @generated from field: uint64 end_offset = 2; 882 | */ 883 | endOffset = protoInt64.zero; 884 | 885 | /** 886 | * @generated from field: exa.language_server_pb.DocumentPosition start_position = 3; 887 | */ 888 | startPosition?: DocumentPosition; 889 | 890 | /** 891 | * @generated from field: exa.language_server_pb.DocumentPosition end_position = 4; 892 | */ 893 | endPosition?: DocumentPosition; 894 | 895 | constructor(data?: PartialMessage) { 896 | super(); 897 | proto3.util.initPartial(data, this); 898 | } 899 | 900 | static readonly runtime: typeof proto3 = proto3; 901 | static readonly typeName = 'exa.language_server_pb.Range'; 902 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 903 | { 904 | no: 1, 905 | name: 'start_offset', 906 | kind: 'scalar', 907 | T: 4 /* ScalarType.UINT64 */ 908 | }, 909 | { no: 2, name: 'end_offset', kind: 'scalar', T: 4 /* ScalarType.UINT64 */ }, 910 | { no: 3, name: 'start_position', kind: 'message', T: DocumentPosition }, 911 | { no: 4, name: 'end_position', kind: 'message', T: DocumentPosition } 912 | ]); 913 | 914 | static fromBinary( 915 | bytes: Uint8Array, 916 | options?: Partial 917 | ): Range { 918 | return new Range().fromBinary(bytes, options); 919 | } 920 | 921 | static fromJson( 922 | jsonValue: JsonValue, 923 | options?: Partial 924 | ): Range { 925 | return new Range().fromJson(jsonValue, options); 926 | } 927 | 928 | static fromJsonString( 929 | jsonString: string, 930 | options?: Partial 931 | ): Range { 932 | return new Range().fromJsonString(jsonString, options); 933 | } 934 | 935 | static equals( 936 | a: Range | PlainMessage | undefined, 937 | b: Range | PlainMessage | undefined 938 | ): boolean { 939 | return proto3.util.equals(Range, a, b); 940 | } 941 | } 942 | 943 | /** 944 | * @generated from message exa.language_server_pb.Suffix 945 | */ 946 | export class Suffix extends Message { 947 | /** 948 | * Text to insert after the cursor when accepting the completion. 949 | * 950 | * @generated from field: string text = 1; 951 | */ 952 | text = ''; 953 | 954 | /** 955 | * Cursor position delta (as signed offset) from the end of the inserted 956 | * completion (including the suffix). 957 | * 958 | * @generated from field: int64 delta_cursor_offset = 2; 959 | */ 960 | deltaCursorOffset = protoInt64.zero; 961 | 962 | constructor(data?: PartialMessage) { 963 | super(); 964 | proto3.util.initPartial(data, this); 965 | } 966 | 967 | static readonly runtime: typeof proto3 = proto3; 968 | static readonly typeName = 'exa.language_server_pb.Suffix'; 969 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 970 | { no: 1, name: 'text', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 971 | { 972 | no: 2, 973 | name: 'delta_cursor_offset', 974 | kind: 'scalar', 975 | T: 3 /* ScalarType.INT64 */ 976 | } 977 | ]); 978 | 979 | static fromBinary( 980 | bytes: Uint8Array, 981 | options?: Partial 982 | ): Suffix { 983 | return new Suffix().fromBinary(bytes, options); 984 | } 985 | 986 | static fromJson( 987 | jsonValue: JsonValue, 988 | options?: Partial 989 | ): Suffix { 990 | return new Suffix().fromJson(jsonValue, options); 991 | } 992 | 993 | static fromJsonString( 994 | jsonString: string, 995 | options?: Partial 996 | ): Suffix { 997 | return new Suffix().fromJsonString(jsonString, options); 998 | } 999 | 1000 | static equals( 1001 | a: Suffix | PlainMessage | undefined, 1002 | b: Suffix | PlainMessage | undefined 1003 | ): boolean { 1004 | return proto3.util.equals(Suffix, a, b); 1005 | } 1006 | } 1007 | 1008 | /** 1009 | * Represents a contiguous part of the completion text that is not 1010 | * already in the document. 1011 | * Next ID: 4, Previous field: prefix. 1012 | * 1013 | * @generated from message exa.language_server_pb.CompletionPart 1014 | */ 1015 | export class CompletionPart extends Message { 1016 | /** 1017 | * @generated from field: string text = 1; 1018 | */ 1019 | text = ''; 1020 | 1021 | /** 1022 | * Offset in the original document where the part starts. For block 1023 | * parts, this is always the end of the line before the block. 1024 | * 1025 | * @generated from field: uint64 offset = 2; 1026 | */ 1027 | offset = protoInt64.zero; 1028 | 1029 | /** 1030 | * @generated from field: exa.language_server_pb.CompletionPartType type = 3; 1031 | */ 1032 | type = CompletionPartType.UNSPECIFIED; 1033 | 1034 | /** 1035 | * The section of the original line that came before this part. Only valid for 1036 | * COMPLETION_PART_TYPE_INLINE. 1037 | * 1038 | * @generated from field: string prefix = 4; 1039 | */ 1040 | prefix = ''; 1041 | 1042 | /** 1043 | * In the case of COMPLETION_PART_TYPE_BLOCK, represents the line it is below. 1044 | * 1045 | * @generated from field: uint64 line = 5; 1046 | */ 1047 | line = protoInt64.zero; 1048 | 1049 | constructor(data?: PartialMessage) { 1050 | super(); 1051 | proto3.util.initPartial(data, this); 1052 | } 1053 | 1054 | static readonly runtime: typeof proto3 = proto3; 1055 | static readonly typeName = 'exa.language_server_pb.CompletionPart'; 1056 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 1057 | { no: 1, name: 'text', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 1058 | { no: 2, name: 'offset', kind: 'scalar', T: 4 /* ScalarType.UINT64 */ }, 1059 | { 1060 | no: 3, 1061 | name: 'type', 1062 | kind: 'enum', 1063 | T: proto3.getEnumType(CompletionPartType) 1064 | }, 1065 | { no: 4, name: 'prefix', kind: 'scalar', T: 9 /* ScalarType.STRING */ }, 1066 | { no: 5, name: 'line', kind: 'scalar', T: 4 /* ScalarType.UINT64 */ } 1067 | ]); 1068 | 1069 | static fromBinary( 1070 | bytes: Uint8Array, 1071 | options?: Partial 1072 | ): CompletionPart { 1073 | return new CompletionPart().fromBinary(bytes, options); 1074 | } 1075 | 1076 | static fromJson( 1077 | jsonValue: JsonValue, 1078 | options?: Partial 1079 | ): CompletionPart { 1080 | return new CompletionPart().fromJson(jsonValue, options); 1081 | } 1082 | 1083 | static fromJsonString( 1084 | jsonString: string, 1085 | options?: Partial 1086 | ): CompletionPart { 1087 | return new CompletionPart().fromJsonString(jsonString, options); 1088 | } 1089 | 1090 | static equals( 1091 | a: CompletionPart | PlainMessage | undefined, 1092 | b: CompletionPart | PlainMessage | undefined 1093 | ): boolean { 1094 | return proto3.util.equals(CompletionPart, a, b); 1095 | } 1096 | } 1097 | 1098 | /** 1099 | * Next ID: 9, Previous field: completion_parts. 1100 | * 1101 | * @generated from message exa.language_server_pb.CompletionItem 1102 | */ 1103 | export class CompletionItem extends Message { 1104 | /** 1105 | * @generated from field: exa.codeium_common_pb.Completion completion = 1; 1106 | */ 1107 | completion?: Completion; 1108 | 1109 | /** 1110 | * @generated from field: exa.language_server_pb.Suffix suffix = 5; 1111 | */ 1112 | suffix?: Suffix; 1113 | 1114 | /** 1115 | * @generated from field: exa.language_server_pb.Range range = 2; 1116 | */ 1117 | range?: Range; 1118 | 1119 | /** 1120 | * @generated from field: exa.codeium_common_pb.CompletionSource source = 3; 1121 | */ 1122 | source = CompletionSource.UNSPECIFIED; 1123 | 1124 | /** 1125 | * @generated from field: repeated exa.language_server_pb.CompletionPart completion_parts = 8; 1126 | */ 1127 | completionParts: CompletionPart[] = []; 1128 | 1129 | constructor(data?: PartialMessage) { 1130 | super(); 1131 | proto3.util.initPartial(data, this); 1132 | } 1133 | 1134 | static readonly runtime: typeof proto3 = proto3; 1135 | static readonly typeName = 'exa.language_server_pb.CompletionItem'; 1136 | static readonly fields: FieldList = proto3.util.newFieldList(() => [ 1137 | { no: 1, name: 'completion', kind: 'message', T: Completion }, 1138 | { no: 5, name: 'suffix', kind: 'message', T: Suffix }, 1139 | { no: 2, name: 'range', kind: 'message', T: Range }, 1140 | { 1141 | no: 3, 1142 | name: 'source', 1143 | kind: 'enum', 1144 | T: proto3.getEnumType(CompletionSource) 1145 | }, 1146 | { 1147 | no: 8, 1148 | name: 'completion_parts', 1149 | kind: 'message', 1150 | T: CompletionPart, 1151 | repeated: true 1152 | } 1153 | ]); 1154 | 1155 | static fromBinary( 1156 | bytes: Uint8Array, 1157 | options?: Partial 1158 | ): CompletionItem { 1159 | return new CompletionItem().fromBinary(bytes, options); 1160 | } 1161 | 1162 | static fromJson( 1163 | jsonValue: JsonValue, 1164 | options?: Partial 1165 | ): CompletionItem { 1166 | return new CompletionItem().fromJson(jsonValue, options); 1167 | } 1168 | 1169 | static fromJsonString( 1170 | jsonString: string, 1171 | options?: Partial 1172 | ): CompletionItem { 1173 | return new CompletionItem().fromJsonString(jsonString, options); 1174 | } 1175 | 1176 | static equals( 1177 | a: CompletionItem | PlainMessage | undefined, 1178 | b: CompletionItem | PlainMessage | undefined 1179 | ): boolean { 1180 | return proto3.util.equals(CompletionItem, a, b); 1181 | } 1182 | } 1183 | -------------------------------------------------------------------------------- /src/codeium.ts: -------------------------------------------------------------------------------- 1 | // Some of this code is based on the code from https://github.com/val-town/codemirror-codeium/blob/main/src/codeium.ts 2 | // licensed under the ISC License: https://github.com/val-town/codemirror-codeium/blob/main/LICENSE 3 | 4 | import { UUID } from '@lumino/coreutils'; 5 | 6 | import { createPromiseClient } from '@connectrpc/connect'; 7 | import { LanguageServerService } from './api/proto/exa/language_server_pb/language_server_connect'; 8 | import { Language } from './api/proto/exa/codeium_common_pb/codeium_common_pb'; 9 | import { createConnectTransport } from '@connectrpc/connect-web'; 10 | import { 11 | Document, 12 | GetCompletionsResponse 13 | } from './api/proto/exa/language_server_pb/language_server_pb'; 14 | import { ICodeiumConfig } from './config'; 15 | import { type PartialMessage } from '@bufbuild/protobuf'; 16 | 17 | const transport = createConnectTransport({ 18 | baseUrl: 'https://server.codeium.com', 19 | useBinaryFormat: true 20 | }); 21 | 22 | const client = createPromiseClient(LanguageServerService, transport); 23 | 24 | const sessionId = UUID.uuid4(); 25 | 26 | export async function getCodeiumCompletions({ 27 | text, 28 | cursorOffset, 29 | config, 30 | otherDocuments 31 | }: { 32 | text: string; 33 | cursorOffset: number; 34 | config: ICodeiumConfig; 35 | otherDocuments: PartialMessage[]; 36 | }) { 37 | const lang = config.language; 38 | const language = Language[lang?.toUpperCase() as keyof typeof Language]; 39 | return await client.getCompletions( 40 | { 41 | metadata: { 42 | // TODO: read metadata from app 43 | ideName: 'web', 44 | ideVersion: '0.0.5', 45 | extensionName: 'TODO', 46 | extensionVersion: '1.0.0', 47 | apiKey: config.apiKey, 48 | sessionId: sessionId, 49 | authSource: config.authSource 50 | }, 51 | document: { 52 | text: text, 53 | cursorOffset: BigInt(cursorOffset), 54 | language, 55 | editorLanguage: lang ?? 'python', 56 | lineEnding: '\n' 57 | }, 58 | editorOptions: { 59 | tabSize: 2n, 60 | insertSpaces: true 61 | }, 62 | otherDocuments: otherDocuments, 63 | multilineConfig: undefined 64 | }, 65 | { 66 | // signal, 67 | headers: { 68 | Authorization: `Basic ${config.apiKey}-${sessionId}` 69 | } 70 | } 71 | ); 72 | } 73 | 74 | export function simplifyCompletions(completions: GetCompletionsResponse) { 75 | return completions.completionItems[0]!.completionParts.filter(part => { 76 | // Type 3 overwrites existing text. Maybe we need this eventually, 77 | // but not right now and it usually is duplicative. 78 | return part.type !== 3; 79 | }).map(part => { 80 | return { 81 | ...part, 82 | offset: Number(part.offset), 83 | text: part.type === 2 ? `\n${part.text}` : part.text 84 | }; 85 | }); 86 | } 87 | -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | // Some of this code is based on the code from https://github.com/val-town/codemirror-codeium/blob/main/src/config.ts 2 | // licensed under the ISC License: https://github.com/val-town/codemirror-codeium/blob/main/LICENSE 3 | 4 | export interface ICodeiumConfig { 5 | /** 6 | * Codeium API key 7 | */ 8 | apiKey: string; 9 | 10 | /** 11 | * The programming language of the given document. 12 | */ 13 | language?: string; 14 | /** 15 | * Time in millseconds after typing to fetch 16 | * completions from codeium 17 | */ 18 | timeout?: number; 19 | 20 | authSource?: number; 21 | } 22 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | JupyterFrontEnd, 3 | JupyterFrontEndPlugin 4 | } from '@jupyterlab/application'; 5 | import { IEditorLanguageRegistry } from '@jupyterlab/codemirror'; 6 | import { ICompletionProviderManager } from '@jupyterlab/completer'; 7 | import { ISettingRegistry } from '@jupyterlab/settingregistry'; 8 | import { CodeiumProvider } from './provider'; 9 | 10 | const plugin: JupyterFrontEndPlugin = { 11 | id: 'jupyterlab-codeium:inline-provider', 12 | autoStart: true, 13 | requires: [ 14 | ICompletionProviderManager, 15 | IEditorLanguageRegistry, 16 | ISettingRegistry 17 | ], 18 | activate: ( 19 | app: JupyterFrontEnd, 20 | manager: ICompletionProviderManager, 21 | editorLanguageRegistry: IEditorLanguageRegistry, 22 | settingRegistry: ISettingRegistry 23 | ): void => { 24 | const provider = new CodeiumProvider({ editorLanguageRegistry }); 25 | manager.registerInlineProvider(provider); 26 | 27 | settingRegistry 28 | .load(plugin.id) 29 | .then(settings => { 30 | const updateKey = () => { 31 | const apiKey = settings.get('apiKey').composite as string; 32 | provider.apiKey = apiKey; 33 | }; 34 | 35 | settings.changed.connect(() => updateKey()); 36 | updateKey(); 37 | }) 38 | .catch(reason => { 39 | console.error(`Failed to load settings for ${plugin.id}`, reason); 40 | }); 41 | } 42 | }; 43 | 44 | export default plugin; 45 | -------------------------------------------------------------------------------- /src/provider.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CompletionHandler, 3 | IInlineCompletionContext, 4 | IInlineCompletionProvider 5 | } from '@jupyterlab/completer'; 6 | 7 | import { IEditorLanguageRegistry } from '@jupyterlab/codemirror'; 8 | 9 | import { getCodeiumCompletions, simplifyCompletions } from './codeium'; 10 | 11 | export class CodeiumProvider implements IInlineCompletionProvider { 12 | readonly identifier = 'codeium'; 13 | readonly name = 'Codeium'; 14 | 15 | constructor(options: CodeiumProvider.IOptions) { 16 | this._editorLanguageRegistry = options.editorLanguageRegistry; 17 | } 18 | 19 | set apiKey(apiKey: string) { 20 | this._apiKey = apiKey; 21 | } 22 | 23 | async fetch( 24 | request: CompletionHandler.IRequest, 25 | context: IInlineCompletionContext 26 | ) { 27 | const { text, offset: cursorOffset, mimeType } = request; 28 | const language = this._editorLanguageRegistry.findByMIME(mimeType ?? ''); 29 | const results = await getCodeiumCompletions({ 30 | text, 31 | cursorOffset, 32 | config: { 33 | apiKey: this._apiKey, 34 | language: language?.support?.language.name 35 | }, 36 | otherDocuments: [] 37 | }); 38 | 39 | const simplified = simplifyCompletions(results).map(part => ({ 40 | from: Number(part.offset), 41 | to: Number(part.offset), 42 | insert: part.text 43 | })); 44 | 45 | return { 46 | items: simplified.map(part => ({ insertText: part.insert })) 47 | }; 48 | } 49 | 50 | private _apiKey = ''; 51 | private _editorLanguageRegistry: IEditorLanguageRegistry; 52 | } 53 | 54 | export namespace CodeiumProvider { 55 | export interface IOptions { 56 | editorLanguageRegistry: IEditorLanguageRegistry; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /style/base.css: -------------------------------------------------------------------------------- 1 | /* 2 | See the JupyterLab Developer Guide for useful CSS Patterns: 3 | 4 | https://jupyterlab.readthedocs.io/en/stable/developer/css.html 5 | */ 6 | -------------------------------------------------------------------------------- /style/index.css: -------------------------------------------------------------------------------- 1 | @import url('base.css'); 2 | -------------------------------------------------------------------------------- /style/index.js: -------------------------------------------------------------------------------- 1 | import './base.css'; 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "composite": true, 5 | "declaration": true, 6 | "esModuleInterop": true, 7 | "incremental": true, 8 | "jsx": "react", 9 | "module": "esnext", 10 | "moduleResolution": "node", 11 | "noEmitOnError": true, 12 | "noImplicitAny": true, 13 | "noUnusedLocals": true, 14 | "preserveWatchOutput": true, 15 | "resolveJsonModule": true, 16 | "outDir": "lib", 17 | "rootDir": "src", 18 | "strict": true, 19 | "strictNullChecks": true, 20 | "target": "ES2020" 21 | }, 22 | "include": ["src/**/*"] 23 | } 24 | --------------------------------------------------------------------------------