├── .github ├── scripts │ ├── vars │ └── version └── workflows │ └── ci.yml ├── Dockerfile ├── LICENSE ├── README.md ├── cmd ├── loader │ └── loader.go ├── root.go └── server │ └── server.go ├── deploy ├── docker-compose │ ├── .gitignore │ ├── README.md │ ├── data │ │ ├── README.md │ │ ├── generate_fake_data.py │ │ ├── points.jsonl │ │ └── targets.jsonl │ └── docker-compose.yml └── pulze-intent-v0.1 │ ├── .gitignore │ ├── README.md │ ├── docker-compose.yml │ └── k8s.yaml ├── docs └── pulze-smart-router.png ├── go.mod ├── go.sum ├── internal ├── loader │ └── loader.go ├── scorespb │ ├── go.mod │ ├── go.sum │ └── scores.pb.go ├── server │ └── server.go └── teipb │ ├── go.mod │ ├── go.sum │ ├── tei.pb.go │ └── tei_grpc.pb.go ├── main.go ├── proto ├── scores │ └── scores.proto └── tei │ └── tei.proto └── scripts └── gen-artifacts.sh /.github/scripts/vars: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cat << EOF > "${GITHUB_OUTPUT}" 6 | image=ghcr.io/${GITHUB_REPOSITORY_OWNER}/$(basename "${PWD}") 7 | version=$("$(dirname $0)"/version) 8 | EOF 9 | -------------------------------------------------------------------------------- /.github/scripts/version: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | # Verify clean tree 6 | [ -z "$(git status --porcelain)" ] || ( echo >&2 "Git tree not clean!" && exit 1 ) 7 | 8 | # Use gitcalver if we are on main 9 | if [ "$(git branch --show-current)" = main ]; then 10 | TZ=UTC 11 | # Prints version in the following format: ._ 12 | # From docker docs: A tag name may contain lowercase and uppercase characters, 13 | # digits, underscores, periods and dashes. A tag name may not start with a period 14 | # or a dash and may contain a maximum of 128 characters. 15 | git log --pretty="format:%cd %h" --date="format-local:%Y%m%d" | \ 16 | awk 'NR==1{d=$1;h=$2}{if(d==$1)c++;else exit}END{print d"."c"_"h}' 17 | else 18 | printf $(git branch --show-current | tr / -)_$(git rev-parse --short HEAD) 19 | fi 20 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build and Push Image 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.ref }} 10 | cancel-in-progress: true 11 | 12 | jobs: 13 | build-and-push-image: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | contents: read 17 | id-token: write 18 | packages: write 19 | steps: 20 | - uses: actions/checkout@v4 21 | with: 22 | fetch-depth: 0 23 | - id: vars 24 | run: .github/scripts/vars 25 | - uses: docker/login-action@v3 26 | with: 27 | registry: ghcr.io 28 | username: ${{ github.actor }} 29 | password: ${{ secrets.GITHUB_TOKEN }} 30 | - uses: docker/setup-buildx-action@v3 31 | - uses: docker/build-push-action@v5 32 | with: 33 | platforms: linux/amd64 34 | push: true 35 | file: Dockerfile 36 | tags: ${{ steps.vars.outputs.image }}:latest,${{ steps.vars.outputs.image }}:${{ steps.vars.outputs.version }} 37 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=${BUILDPLATFORM} golang:alpine AS builder 2 | 3 | ARG TARGETARCH 4 | ENV GOARCH "${TARGETARCH}" 5 | ENV GOOS linux 6 | 7 | WORKDIR /build 8 | 9 | COPY go.mod go.sum ./ 10 | COPY internal/scorespb/ internal/scorespb/ 11 | COPY internal/teipb/ internal/teipb/ 12 | RUN go mod download 13 | COPY ./ ./ 14 | RUN go build -ldflags="-w -s" -o dist/knn-router main.go 15 | 16 | FROM scratch 17 | COPY --from=builder /build/dist/knn-router /knn-router 18 | ENTRYPOINT [ "/knn-router" ] 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KNN Router 2 | 3 | A minimal server for generating a ranked list of targets, for a query, based on its k-nearest semantic neighbors. Written in Go. 4 | 5 | KNN-router can be used within a larger system to route natural language queries to the right system, with minimal latency. Given a user query, KNN-router: 6 | 7 | 1. Looks up the most semantically similar neighbors from a curated corpus of example utterances 8 | 2. Computes a weighted average score (based on the distances between query and top-K example utterances) for each target associated with the respective utterances. Targets can be information retrieval systems, agents, LORA adapters, Small/Large Language Models, or others. The sky is the limit! 9 | 3. Returns a ranked list of targets that are most suitable for satisfying the query 10 | 11 | At [Pulze.ai](https://platform.pulze.ai), we use KNN-router to select the best LLM for user requests. Try it out locally [here](./deploy/pulze-intent-v0.1/). 12 | ![Pulze Smart Router](./docs/pulze-smart-router.png) 13 | 14 | Works with: 15 | 16 | - Embeddings: [HuggingFace Text Embeddings Inference](https://github.com/huggingface/text-embeddings-inference) 17 | - Vector Store: [Qdrant](https://github.com/qdrant/qdrant) 18 | - Database: [Bolt](https://github.com/etcd-io/bbolt) 19 | 20 | ## Usage 21 | 22 | ### Quickstart 23 | 24 | See this [example](./deploy/docker-compose) for getting started locally. 25 | 26 | ### Generating deployment artifacts 27 | 28 | Dependencies: 29 | 30 | - [`points.jsonl`](./deploy/docker-compose/data/points.jsonl): JSONL-formatted file containing points and their respective categories and embeddings. Each line should contain the following fields: `point_uid`, `category`, and `embedding`. 31 | - [`targets.jsonl`](./deploy/docker-compose/data/targets.jsonl): JSONL-formatted file containing the targets and their respective scores for each point. Each line should contain the following fields: `point_uid`, `target`, and `score`. 32 | 33 | The following artifacts are required for deployment: 34 | 35 | - `embeddings.snapshot`: Snapshot of Qdrant collection containing the point embeddings 36 | - `scores.db`: Bolt DB containing the targets and their respective scores for each point 37 | 38 | Use this [script](./scripts/gen-artifacts.sh) to generate these artifacts: 39 | 40 | ```bash 41 | scripts/gen-artifacts.sh --points-data-path points.jsonl --scores-data-path targets.jsonl --output-dir ./dist 42 | ``` 43 | 44 | ## TODOs 45 | 46 | - [ ] Helm chart 47 | - [ ] GRPC endpoint 48 | -------------------------------------------------------------------------------- /cmd/loader/loader.go: -------------------------------------------------------------------------------- 1 | package loader 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/pulzeai-oss/knn-router/internal/loader" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | type loaderOpts struct { 11 | DBPath string 12 | pointsDataPath string 13 | scoresDataPath string 14 | } 15 | 16 | var opts loaderOpts 17 | 18 | var LoaderCmd = &cobra.Command{ 19 | Use: "load", 20 | Short: "Write dataset to database", 21 | Run: func(cmd *cobra.Command, args []string) { 22 | loader := loader.NewLoader() 23 | if err := loader.LoadPoints(opts.pointsDataPath); err != nil { 24 | log.Fatalf("failed to load points: %v", err) 25 | } 26 | if err := loader.LoadScores(opts.scoresDataPath); err != nil { 27 | log.Fatalf("failed to load scores: %v", err) 28 | } 29 | if err := loader.SaveScores(opts.DBPath); err != nil { 30 | log.Fatalf("failed to write to DB: %v", err) 31 | } 32 | }, 33 | } 34 | 35 | func init() { 36 | LoaderCmd.Flags(). 37 | StringVar(&opts.pointsDataPath, "points-data-path", "", "Path to JSONL-formatted dataset containing points") 38 | LoaderCmd.Flags(). 39 | StringVar(&opts.scoresDataPath, "scores-data-path", "", "Path to JSONL-formatted dataset containing target scores") 40 | LoaderCmd.Flags(). 41 | StringVar(&opts.DBPath, "db-path", "scores.db", "The path to write Bolt database to") 42 | } 43 | -------------------------------------------------------------------------------- /cmd/root.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/pulzeai-oss/knn-router/cmd/loader" 5 | "github.com/pulzeai-oss/knn-router/cmd/server" 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | var rootCmd = &cobra.Command{ 10 | Use: "knn-router [subcommand]", 11 | Short: "The CLI for KNN-router", 12 | } 13 | 14 | func init() { 15 | rootCmd.AddCommand(server.ServerCmd) 16 | rootCmd.AddCommand(loader.LoaderCmd) 17 | } 18 | 19 | func Execute() error { 20 | return rootCmd.Execute() 21 | } 22 | -------------------------------------------------------------------------------- /cmd/server/server.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "context" 5 | "log" 6 | 7 | "github.com/pulzeai-oss/knn-router/internal/server" 8 | "github.com/pulzeai-oss/knn-router/internal/teipb" 9 | "github.com/spf13/cobra" 10 | bolt "go.etcd.io/bbolt" 11 | "google.golang.org/grpc" 12 | "google.golang.org/grpc/credentials/insecure" 13 | ) 14 | 15 | type serverOpts struct { 16 | bindAddr string 17 | embedAddr string 18 | qdrantAddr string 19 | DBPath string 20 | topK int 21 | } 22 | 23 | var opts serverOpts 24 | 25 | var ServerCmd = &cobra.Command{ 26 | Use: "server", 27 | Short: "Start the KNN-router server", 28 | Run: func(cmd *cobra.Command, args []string) { 29 | DB, err := bolt.Open(opts.DBPath, 0600, &bolt.Options{ReadOnly: true}) 30 | if err != nil { 31 | log.Fatalf("failed to open scores database: %v", err) 32 | } 33 | defer DB.Close() 34 | 35 | embedConn, err := grpc.DialContext( 36 | context.Background(), 37 | opts.embedAddr, 38 | grpc.WithTransportCredentials(insecure.NewCredentials()), 39 | ) 40 | if err != nil { 41 | log.Fatalf("failed to create connection to embedding server: %v", err) 42 | } 43 | defer embedConn.Close() 44 | 45 | infoClient := teipb.NewInfoClient(embedConn) 46 | infoResp, err := infoClient.Info(context.Background(), &teipb.InfoRequest{}) 47 | if err != nil { 48 | log.Fatalf("failed to get info from embedding server: %v", err) 49 | } 50 | 51 | qdrantConn, err := grpc.DialContext( 52 | context.Background(), 53 | opts.qdrantAddr, 54 | grpc.WithTransportCredentials(insecure.NewCredentials()), 55 | ) 56 | if err != nil { 57 | log.Fatalf("failed to create connection to Qdrant server: %v", err) 58 | } 59 | defer qdrantConn.Close() 60 | 61 | svr := server.NewServer( 62 | embedConn, 63 | qdrantConn, 64 | DB, 65 | opts.topK, 66 | int(infoResp.MaxInputLength), 67 | ) 68 | if err := svr.ListenAndServe(opts.bindAddr); err != nil { 69 | log.Fatalf("failed to start server: %v", err) 70 | } 71 | }, 72 | } 73 | 74 | func init() { 75 | ServerCmd.Flags(). 76 | StringVarP(&opts.bindAddr, "bind-addr", "a", ":8888", "Address and port to bind the server to") 77 | ServerCmd.Flags(). 78 | StringVarP(&opts.embedAddr, "embed-address", "e", "localhost:8889", "Address and port of the embedding inference server") 79 | ServerCmd.Flags(). 80 | StringVarP(&opts.qdrantAddr, "qdrant-address", "q", "localhost:6334", "Address and port of the Qdrant server") 81 | ServerCmd.Flags(). 82 | StringVarP(&opts.DBPath, "db-path", "s", "scores.db", "The path to the Bolt database") 83 | ServerCmd.Flags(). 84 | IntVarP(&opts.topK, "top-k", "k", 10, "The number of top hits to aggregate") 85 | } 86 | -------------------------------------------------------------------------------- /deploy/docker-compose/.gitignore: -------------------------------------------------------------------------------- 1 | embeddings.snapshot 2 | scores.db 3 | -------------------------------------------------------------------------------- /deploy/docker-compose/README.md: -------------------------------------------------------------------------------- 1 | # Docker Compose Deployment 2 | 3 | As part of this quickstart, we present a dummy example that selects the most appropriate agent (i.e. `chitchat-agent` or `politics-agent`) for chit-chat and political queries respectively. 4 | The example utterances are defined in [`./data/points.jsonl`](./data/points.jsonl), and the target agents and their corresponding score for each utterance are defined in [`./data/targets.jsonl`](./data/targets.jsonl). 5 | 6 | ## Usage 7 | 8 | Generate deployment artifacts: 9 | 10 | ```bash 11 | ../../scripts/gen-artifacts.sh --points-data-path data/points.jsonl --scores-data-path data/targets.jsonl --output-dir . 12 | ``` 13 | 14 | Start the services: 15 | 16 | ```bash 17 | docker compose up -d --build 18 | ``` 19 | 20 | Get target scores for query: 21 | 22 | ```bash 23 | curl -s 127.0.0.1:8888/ \ 24 | -X POST \ 25 | -d '{"query":"who are the candidates running for office?"}' \ 26 | -H 'Content-Type: application/json' | jq . 27 | ``` 28 | 29 | Output: 30 | 31 | ``` 32 | { 33 | "hits": [ 34 | { 35 | "id": "887cd819-15f5-4c27-a17b-532fec485271", 36 | "category": "politics", 37 | "similarity": 0.52368176 38 | }, 39 | { 40 | "id": "3d0c0974-0d99-41fd-b7b1-4dfc9155d53f", 41 | "category": "politics", 42 | "similarity": 0.48429558 43 | }, 44 | { 45 | "id": "442ae99e-c4d4-4316-9067-3b7232f23754", 46 | "category": "politics", 47 | "similarity": 0.47992623 48 | }, 49 | { 50 | "id": "485d0e5b-599f-4844-99ab-d86f376c3214", 51 | "category": "politics", 52 | "similarity": 0.4750255 53 | }, 54 | { 55 | "id": "b9c076c0-e96c-4208-88ec-761b325ca12e", 56 | "category": "politics", 57 | "similarity": 0.46624953 58 | }, 59 | { 60 | "id": "9d7d61c1-a922-456c-913f-3c3a51beb8aa", 61 | "category": "chitchat", 62 | "similarity": 0.4377066 63 | }, 64 | { 65 | "id": "8453a119-eff9-4473-bbb9-359adf9bf4c0", 66 | "category": "chitchat", 67 | "similarity": 0.43222725 68 | }, 69 | { 70 | "id": "82dafcc6-b4eb-4ea1-967c-5d21453d881c", 71 | "category": "chitchat", 72 | "similarity": 0.41400117 73 | }, 74 | { 75 | "id": "b9784f9c-ace9-4939-87d3-83e28dc44b5e", 76 | "category": "chitchat", 77 | "similarity": 0.39327258 78 | }, 79 | { 80 | "id": "7f2ad3ce-4505-4d3b-89c1-178abc1aee80", 81 | "category": "chitchat", 82 | "similarity": 0.3586356 83 | } 84 | ], 85 | "scores": [ 86 | { 87 | "target": "politics-agent", 88 | "score": 0.54 89 | }, 90 | { 91 | "target": "chitchat-agent", 92 | "score": 0.46 93 | } 94 | ] 95 | } 96 | ``` 97 | -------------------------------------------------------------------------------- /deploy/docker-compose/data/README.md: -------------------------------------------------------------------------------- 1 | # Fake data generation 2 | 3 | Install the necessary dependencies: 4 | 5 | ```bash 6 | pip install pandas sentence-transformers 7 | ``` 8 | 9 | Run the data generation script: 10 | 11 | ```bash 12 | python generate_fake_data.py 13 | ``` 14 | -------------------------------------------------------------------------------- /deploy/docker-compose/data/generate_fake_data.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | 3 | import pandas as pd 4 | from sentence_transformers import SentenceTransformer 5 | 6 | 7 | def _fake_points(): 8 | embedding_model = SentenceTransformer("BAAI/bge-small-en-v1.5") 9 | df = pd.DataFrame( 10 | [ 11 | *[ 12 | { 13 | "point_uid": str(uuid.uuid4()), 14 | "category": "politics", 15 | "utterance": utterance, 16 | } 17 | for utterance in [ 18 | "isn't politics the best thing ever", 19 | "why don't you tell me about your political opinions", 20 | "don't you just love the president", 21 | "they're going to destroy this country!", 22 | "they will save the country!", 23 | ] 24 | ], 25 | *[ 26 | { 27 | "point_uid": str(uuid.uuid4()), 28 | "category": "chitchat", 29 | "utterance": utterance, 30 | } 31 | for utterance in [ 32 | "how's the weather today?", 33 | "how are things going?", 34 | "lovely weather today", 35 | "the weather is horrendous", 36 | "let's go to the chippy", 37 | ] 38 | ], 39 | ] 40 | ) 41 | df["embedding"] = embedding_model.encode(df["utterance"].tolist()).tolist() 42 | return df 43 | 44 | 45 | def _fake_targets(points): 46 | return pd.DataFrame( 47 | [ 48 | { 49 | "point_uid": point["point_uid"], 50 | "target": "politics-agent" 51 | if point["category"] == "politics" 52 | else "chitchat-agent", 53 | "score": 1, 54 | } 55 | for _, point in points.iterrows() 56 | ] 57 | ) 58 | 59 | 60 | if __name__ == "__main__": 61 | points = _fake_points() 62 | with open("points.jsonl", "w") as f: 63 | print(points.to_json(orient="records", lines=True), file=f) 64 | targets = _fake_targets(points) 65 | with open("targets.jsonl", "w") as f: 66 | print(targets.to_json(orient="records", lines=True), file=f) 67 | -------------------------------------------------------------------------------- /deploy/docker-compose/data/points.jsonl: -------------------------------------------------------------------------------- 1 | {"point_uid":"485d0e5b-599f-4844-99ab-d86f376c3214","category":"politics","utterance":"isn't politics the best thing ever","embedding":[-0.0057599857,-0.0012335972,0.0203300137,-0.0202085674,0.0311108045,-0.0434355885,0.0822252855,-0.0383561067,-0.0076945322,0.049373243,0.0296519473,0.0735632926,0.0439698547,0.0267673451,-0.0184437707,-0.0134058371,0.0421767719,-0.0458476357,-0.0688014254,0.0539454781,0.0446471944,-0.0130159585,-0.0036677804,-0.027946949,0.014291198,0.0040719202,-0.0124405632,0.0019649388,-0.0348324403,-0.0773273557,0.0128426095,-0.0776474327,-0.0550417379,0.0458252877,0.0108726975,0.0502332263,0.0393664576,-0.0713839158,-0.0359994844,0.0587386265,-0.044775635,0.0531195849,-0.09612225,-0.0080544725,-0.0034949223,-0.0545755923,0.0370775834,0.0032608847,-0.0110102212,0.0017630141,-0.0287521947,0.0668114647,-0.0555538423,0.0092564495,0.0360100083,0.050983537,0.0112346336,-0.0005875385,-0.0095380796,-0.0283658095,-0.0095634926,0.0413487628,-0.1086953878,0.0678370669,0.0916982964,-0.023905687,-0.0125146694,-0.0623746812,-0.0876917467,-0.0164222289,0.0098860813,0.0552520975,0.057254374,0.034909118,0.0702069923,-0.0242034364,0.0097173471,-0.035287112,-0.0142603219,0.0099521652,0.0334701687,-0.0085118925,-0.018555589,0.0183705147,0.0122613981,-0.0225823987,-0.0270919632,-0.0085006924,-0.0466113687,0.0501930788,-0.0258306563,0.0338453352,0.04432844,-0.0001099706,0.0066324077,-0.0079529649,-0.0325607806,0.0062049073,-0.0042087729,0.3244749606,-0.1129805222,0.0427374095,0.0321063437,-0.0619386919,0.0379889198,-0.0301708598,0.0273257792,-0.0335798934,-0.0196884666,0.0026219757,0.0324990079,-0.0740546733,0.0451314077,-0.0011528138,0.0296713989,-0.0722215325,0.0722303316,-0.0124560865,0.0009039695,0.023021508,-0.0370716974,0.0357989408,0.0270666387,-0.0367969088,0.0034730379,-0.0615352578,0.0296944398,0.0198912788,0.0287085045,-0.0459524207,0.0110357897,-0.0770561323,-0.0158420112,-0.0293501355,0.0191817041,-0.0928170234,-0.0259546526,0.0476963483,-0.0012805316,0.0382104777,0.0183936637,-0.0794218257,-0.0286222734,-0.0827474594,-0.0772720054,0.0009943772,0.0007025311,0.0174596887,-0.0207838099,0.0658094436,-0.0366652682,-0.0259107053,-0.0153226294,-0.0514731221,0.0287106019,-0.0496511459,-0.0081068426,-0.0046414873,-0.0315269306,-0.0680695251,0.0468755923,-0.0149376718,0.0004564403,0.0478715561,-0.0423019789,-0.0322424881,-0.0318790562,0.0171386953,0.0009950593,0.0509150736,0.0261381064,0.0114833005,-0.0136429518,0.0438249968,0.1200246662,-0.0603024103,0.0154295312,0.040902961,-0.0180182122,-0.0006554773,0.0914872438,0.0197164733,-0.0292918812,0.0059743263,0.0428594798,0.0739447251,-0.0173805654,-0.021828277,0.0103014158,0.0042979009,0.0351004079,0.0845629871,0.0274799895,-0.0042426619,-0.0397695377,-0.0392779224,0.0225447696,-0.0406235866,0.0583246648,0.0320023037,-0.1409100294,-0.0527139194,-0.0951216295,0.0052236523,0.0638055429,-0.007449029,-0.0012687955,-0.0037354024,0.0437700413,0.0149099724,-0.0872462913,-0.0581643619,0.0251460914,-0.0112485094,-0.0054174298,-0.0246744696,0.0218445938,0.0456328467,-0.0633882433,-0.0188595802,-0.0073872777,-0.0026186039,0.0189661253,-0.31809026,-0.0234223697,-0.0678072125,-0.0005871416,0.0988356918,-0.0270705074,0.0164576806,-0.0158124268,-0.0094461404,0.1008041874,-0.0197337922,0.0129383141,-0.0079108858,0.0191123597,-0.047145281,-0.0025566362,-0.0284913462,-0.008496982,-0.0500187464,0.0794241354,0.0065963259,-0.008084693,0.0169675257,-0.0535761155,0.0547133125,-0.0324593,0.1512657553,0.0194807146,0.0373935103,0.0695051551,0.046134565,-0.0090342881,-0.0395968109,-0.1489414871,0.0747296065,0.0881244168,0.023601152,-0.0381876789,-0.0813934803,0.0165910739,0.0098158298,-0.0274443869,-0.0320067145,-0.0622300766,-0.0393133238,-0.0916831791,0.0123561323,0.0300732516,-0.0784823447,-0.0010290424,-0.0100295329,-0.0352023393,0.038588386,0.0047275298,0.027340157,0.0295796972,-0.0680689812,-0.0211169962,0.0137357656,0.0622198842,0.0054791654,-0.0001960205,-0.0384252109,-0.0045705084,-0.0119665358,0.0554211996,0.0118188402,-0.0101828622,0.0001192807,0.0140503943,-0.0492412373,0.0545626916,-0.0351052843,-0.0318015479,0.0355543792,0.0309908856,0.0788297206,0.0466360189,0.0064638071,-0.0064416938,0.0292527154,0.0707983747,0.0250450317,-0.0479881875,-0.0137305856,-0.0384058282,-0.0631333739,-0.0834572092,-0.0098976679,-0.0489154384,0.0189828463,0.0286203716,-0.046404507,0.0209233388,0.0469369143,-0.0257738158,-0.180624336,-0.0080276756,-0.0422509052,0.0043190932,-0.0257583242,-0.0113992207,-0.034195058,0.0478933826,-0.0524872243,0.0130515359,0.0533485077,0.105854243,-0.0244918484,0.0009706448,-0.0169317406,0.0017306405,0.0635870025,-0.0068111881,0.0326024964,0.0171405841,0.0708267689,0.002236072,0.0860964805,0.0043510422,0.036923565,-0.0015978925,-0.0167451464,0.0264900606,-0.0786811486,-0.0254168212,0.0318776667,0.0114234025,0.016791882,-0.0713906288,0.0225603934,0.0010065683,0.0710293725,0.0216583051,-0.000573634,-0.0481028892,-0.0259588975,0.08132153,0.0232609659,0.0010028563,0.0792255998,-0.0953461081,0.0050312006,0.0179065187,0.0756506175,0.0248501413,-0.0094897971,0.0192994159,-0.0166954882,0.0577258468,-0.017451847,0.0624286383,-0.0350083038,0.0524606854,0.0545946769,0.0126612457,-0.0340788439,0.039792072,0.0005012957,0.1236026883,0.0027132954]} 2 | {"point_uid":"442ae99e-c4d4-4316-9067-3b7232f23754","category":"politics","utterance":"why don't you tell me about your political opinions","embedding":[0.0015410507,0.0241646562,0.0259754751,-0.0242278222,0.0078529669,0.0406987295,0.0583681017,0.0539074503,-0.0055743572,0.0013124908,0.0054634642,0.0380491987,0.0204085857,0.0480010957,0.0577905364,0.0378182754,0.0176916104,-0.068952769,-0.0786443055,0.0075556547,-0.0080050109,0.0216291044,-0.0234219786,0.0340457074,-0.023580214,-0.0313586891,0.0007125074,0.0126607781,-0.0958513692,-0.0622331351,0.0736220479,-0.0439275689,0.020342106,0.0047593527,0.0891452134,-0.026175335,0.0177555438,-0.0073126503,-0.0327623375,0.01260537,-0.0048161228,-0.0226564053,0.0292881913,-0.0094591184,0.0184862725,-0.0245058574,0.0400422066,0.0328895412,0.0034868775,-0.0137025975,-0.0287413783,0.0190650411,-0.024434505,-0.0652566552,0.0169495009,0.0475599654,0.0024517106,0.0043892572,-0.0130687393,-0.004771342,0.0227897055,0.0240796059,-0.1180441082,0.0628147274,0.0127991894,0.0574878827,-0.0344275199,-0.0328250453,-0.0327571556,-0.0135686034,0.0146050649,0.0073847608,-0.0088881347,0.049714148,-0.0064563076,-0.0375518426,0.0064988197,0.0705828443,0.0319458693,-0.0570794605,-0.0177001115,0.034279149,-0.060511142,-0.0182836615,0.0444566198,-0.0559125021,0.0255835596,0.0604140721,-0.037573047,0.0404933691,0.0175940003,-0.0333919749,0.0298595466,0.026725648,-0.0616564415,-0.038232334,0.0160975754,0.0568630546,-0.143461138,0.3490082324,-0.0421019197,0.0170302261,0.0211949591,-0.0295360815,-0.0001583119,0.0028238429,-0.0041594836,0.0276650712,0.0084859775,0.016415149,0.0738616288,-0.0317436196,0.0015585868,-0.0285334066,0.0574476421,-0.019126622,0.0724435002,-0.0165337604,-0.0673734993,-0.0209610518,-0.0651298314,0.0192190874,0.0033734862,-0.009507861,0.0913762674,-0.0635701567,-0.0057653966,0.0641668141,0.0258449744,0.0112815471,-0.0158803612,-0.0754559636,-0.0150698554,-0.05661235,0.0151100857,-0.0667645484,-0.0656421632,0.0498398505,0.0475547723,0.0110543277,-0.0154285217,-0.044929374,-0.0360631458,0.0017568398,-0.0123068467,0.0273644403,-0.0658240989,-0.0056251548,-0.0279021319,0.0403204933,-0.0285821017,-0.0041012117,-0.0766306892,-0.0870207399,0.089072071,-0.0305374954,-0.0259791669,-0.0131379496,-0.0388733372,0.0148897991,0.1037996337,-0.0224797446,0.0190757141,-0.0009467559,-0.0222536642,-0.0541447327,-0.032875251,-0.0132171083,0.0860350952,-0.0066442871,0.0383396111,0.041962713,0.0240270775,-0.0460846573,0.1233467683,-0.0563923456,-0.0072524669,0.0263877716,0.0423465222,0.0106332386,0.0380701795,0.0093734004,0.0087488238,0.0482964963,-0.0422959216,-0.0297812168,-0.0693923756,-0.0531219728,-0.028170554,0.0053395783,0.0010244559,0.0095609669,0.0056095119,0.0291316919,-0.0957017988,-0.0693612248,0.0748830363,-0.0254800878,0.0059632645,0.0078515848,-0.0682304725,-0.0378034785,-0.0439304151,0.1039866582,-0.0148463678,0.0366608351,0.0186291933,-0.0429972112,0.0996607766,0.0187931005,-0.0254522935,0.0017038463,0.0284437686,-0.0221330691,-0.0100043574,0.0003810196,0.0092584649,-0.0041167801,0.0281565096,-0.0277941879,0.0188610256,0.0258133952,-0.0325922817,-0.2812370062,-0.0175011978,-0.0609761849,-0.0012736397,0.0281747617,-0.0831467733,0.0884371027,0.0221542213,-0.0383588113,0.1413490176,0.0123405168,0.0239614956,-0.0383908339,-0.0195024498,-0.0335455462,0.0004908072,-0.0671320185,0.0687489957,-0.0532405116,0.0269691534,0.0020483867,0.0046716197,-0.0059065423,-0.0549926981,0.0519153476,-0.0330900811,0.1538248211,0.0563492328,-0.0092026154,0.029396804,0.0333092622,0.0656100288,-0.0509096757,-0.1314905137,-0.0098356996,0.0115908338,-0.0495551489,-0.0116788512,-0.0286109671,0.0195103474,-0.0211990867,-0.0046636043,-0.0361491367,-0.020256279,-0.0432586484,-0.0681230128,0.0126512311,0.0246913228,-0.0469420925,0.0214710329,0.0027276131,-0.015327544,0.0909734815,0.0527429543,0.0261344984,-0.0192851946,-0.0791901872,-0.0012801861,0.0350361727,0.1024897918,-0.0280450732,0.0548031069,0.0021206243,-0.0523801744,-0.0267829299,0.1241130009,-0.0740693212,-0.0148625858,-0.0192092415,0.0381883979,0.001254056,0.0588742755,-0.0443871468,0.0221426692,0.0389717035,0.0060916278,0.0630425364,0.0015417215,0.0115327947,-0.040422529,0.0190006923,0.0338489562,0.0090305647,-0.0008718604,-0.0252417177,0.0075739934,-0.0570438839,-0.036725685,0.082237035,0.0269460846,-0.0040563806,0.0520975627,-0.0153116789,-0.0166718848,0.0015102653,-0.0545612425,-0.1878634542,-0.0001326059,0.0684836209,0.0465262756,0.0248325653,-0.0023540452,0.0309477877,-0.0419919379,-0.1108926684,-0.0305775683,0.0122843897,0.0628790185,-0.0734836757,-0.0745143369,0.0065272921,0.01828444,0.0863295496,0.0282801539,0.0064405343,0.0259546544,0.030326277,-0.0140398741,0.1104538664,0.0858156085,0.0083834575,-0.059547998,-0.0143596707,0.00803582,-0.0442476086,0.0065426631,-0.0162493456,-0.0264219157,-0.0081088468,-0.037984591,-0.0315450057,-0.0883282423,0.0248305872,0.0056389929,0.0055945572,-0.0415726081,-0.0217796396,0.0123225721,-0.0079716211,-0.0119931633,0.0577676781,-0.0480571687,-0.0039843395,0.0454495996,0.0275205262,-0.039902322,-0.0034485441,-0.0502081588,-0.0408088155,0.0513325408,0.069707185,0.0673134923,-0.0173445847,0.0141628208,0.0505585335,0.0102587771,-0.0262392443,-0.0179254524,0.1106286198,-0.0215771552,0.0054248376]} 3 | {"point_uid":"b9c076c0-e96c-4208-88ec-761b325ca12e","category":"politics","utterance":"don't you just love the president","embedding":[-0.0349188671,0.0384383909,0.058772102,-0.0384936184,0.0265138615,-0.0046663946,0.1205573454,0.0014118463,0.0418642387,-0.0224324167,0.0525181703,0.0684261918,0.0412506759,0.0161768924,0.0059059653,-0.0087739062,0.0128237996,0.0130987056,-0.1098282337,0.0219253078,0.030522164,0.0250335392,0.0216473751,-0.018239256,-0.0318268761,-0.017525332,-0.0107735945,0.0067842975,-0.0638927221,-0.0560978428,0.0327308178,-0.0343001522,-0.0216335971,-0.0114353681,0.0486004315,-0.0157252606,0.018293364,0.009284731,-0.0202327985,-0.0049458272,-0.0053689675,-0.0348789021,-0.0245150235,-0.0237797685,-0.0434708074,-0.0314778201,0.0073593473,0.0252969116,0.056804426,0.0319070667,0.0506537855,0.0232943781,-0.0652989596,0.0357752666,-0.0269755777,0.0957771614,0.03071036,-0.0416750051,-0.0384179652,-0.0090969019,0.0076253624,0.0368728936,-0.1908233315,0.0278869402,-0.0080420421,-0.0648044944,0.0566073991,-0.0181538276,-0.0653790608,0.0242315922,0.0188966468,-0.0081114629,0.0191991497,-0.0556567237,-0.0130401766,-0.0213828143,-0.0586490519,0.0194965545,-0.0244736876,-0.0248740371,0.047333207,-0.0577119663,-0.0156933479,-0.0122180032,0.0009368011,-0.0699562952,-0.045298975,-0.0530181415,-0.058385957,0.0815449804,0.0302594099,-0.0633516833,0.0227095876,0.0199860912,-0.0701069757,-0.0046252385,0.0053119431,-0.0227362253,-0.0506387427,0.2809615433,-0.104681395,0.060352724,0.0365275256,-0.0592829399,-0.0107481834,0.0320135541,0.0316784531,0.0339318551,-0.002943401,0.0082806507,0.0902483389,-0.0173820537,0.0571797229,-0.0692160204,0.0640002713,-0.0708893836,-0.0102649061,0.0368180461,-0.0179969706,-0.0639836714,0.0104984259,-0.0167973805,0.0077008903,-0.0325911045,0.0947584435,-0.0938443691,0.0990491733,0.0022567194,0.0227910727,0.0667837709,0.0148765463,-0.0452777147,-0.0467643403,-0.008659916,0.0014597604,-0.0164078027,-0.0409308933,0.0136070224,0.0197731145,0.0586046204,0.0162882488,-0.0510450415,-0.0945023373,-0.1039333344,-0.0057777436,0.0048636911,0.0065194191,0.0141872186,-0.0168991555,0.0663778037,-0.0175011009,0.0068099545,0.0227588844,0.0088982293,0.0507958308,-0.006204362,-0.0323889181,0.053801652,0.0076917214,0.0094614718,0.0710012317,-0.0271296613,0.0300052203,-0.0448504351,0.0257259775,-0.0895425528,-0.0277556609,-0.0329018757,0.0505109988,0.0014853914,-0.0041919299,0.0410644636,-0.0670930147,-0.0112109911,0.1631417871,0.0311461184,0.0275884047,0.0311939158,0.0066055418,0.0304840002,0.0698739812,-0.0426195152,-0.0212060194,-0.0035229963,0.0181837436,0.0636502206,0.0225027222,-0.0117258132,0.0273502246,-0.0096576093,0.0697148144,0.1074040681,-0.0158292484,-0.0252154339,-0.0797729045,-0.0438463911,-0.0195696354,0.0078058979,-0.0312563926,0.068881236,-0.0849687234,-0.030397635,-0.0531110391,0.0189098157,0.1275624782,0.0360283107,0.0025875221,0.0437354371,0.0230385009,-0.0047027036,-0.0433951318,-0.0148747489,0.0274088196,0.0220884793,-0.0314538665,0.0113286301,0.0433567241,0.0901424065,-0.0268775504,-0.0747438446,0.0427697264,0.0121606383,0.0038652881,-0.2468175441,-0.0256283171,-0.1157740355,0.0064951121,0.0423051603,-0.0311333127,0.007845914,-0.0084734214,0.0364360027,0.0303633921,-0.0389806591,-0.0133495079,-0.0315933414,-0.003860269,0.0296244342,0.0148475552,0.0028089965,0.0277296118,-0.0158033557,0.0617699213,-0.0059038186,0.0124866404,-0.048855491,-0.0177614838,0.0216950402,-0.0888779983,0.0850051418,0.0624564439,0.0439495072,0.0133256754,0.0154614672,-0.0388038307,-0.0275439564,-0.147754252,0.0171245635,0.1371237934,0.0154301664,-0.0530424565,-0.0261230208,0.0150856571,-0.016468605,0.0397264697,-0.0408678539,-0.0736167505,-0.0058182208,-0.0729918107,0.0225826036,-0.0025583126,-0.0227875318,0.0083951168,0.0299422033,-0.0754972175,-0.0074025737,-0.0332325399,-0.0256378632,-0.02051262,0.0079154838,-0.0433446616,-0.0118102301,0.0959600583,-0.035126444,-0.0234343,-0.0490505621,-0.0238105953,-0.0460452549,0.0460907146,-0.0329327919,0.0619686395,0.0294076614,0.0112012159,-0.0442803763,-0.0510035045,-0.0502589941,-0.0104043782,-0.0082091279,0.058196485,0.042550534,0.0270172358,-0.0518970042,-0.049170319,0.0046836259,0.0593548305,-0.052080024,-0.0066409674,-0.0075506512,0.0000488257,-0.0783722252,-0.0319680311,0.0119147301,-0.0801339597,-0.0041988003,0.0022239834,0.0378556959,-0.0074561588,-0.0051939893,0.0192778651,-0.1805161834,0.0331112519,-0.0638768375,0.0046083694,-0.0076833707,0.0139658572,0.0627183691,0.0064893514,-0.0815006495,0.0660878718,0.0380810089,0.0441786386,0.0007290383,0.0007343009,0.0268092323,0.0340453126,0.0425034799,-0.0321550034,0.0397216938,0.0479393043,0.0601645,-0.000411022,0.1458414793,0.0062941862,0.0586060137,0.0063941325,-0.0055474504,0.0343924984,-0.0012530157,-0.052986607,0.0317782946,0.0213106312,0.0230165571,-0.1005737931,0.0720353648,0.0434580073,-0.0120641934,0.0729047284,-0.0563971512,-0.0558312796,-0.0597079657,0.0911793634,0.0492072217,-0.0649637356,0.0632769763,-0.0221693255,0.04222982,0.0493496917,-0.0232545249,0.0173425078,0.0360890068,-0.0789851546,-0.0182523709,0.0246277545,-0.0002874996,-0.0027693815,-0.0178426076,0.0037249061,0.0218506213,0.0015722049,-0.0649063885,0.0409318022,0.0531921051,0.0717021152,0.0085739596]} 4 | {"point_uid":"3d0c0974-0d99-41fd-b7b1-4dfc9155d53f","category":"politics","utterance":"they're going to destroy this country!","embedding":[-0.0041483818,-0.0132096428,0.0250662901,0.0391318612,0.1244832948,0.028296506,0.0327389017,0.0234072078,-0.0405155234,0.0260083955,-0.0089043994,-0.0172036085,0.0269641727,0.0127197783,-0.0044944668,-0.0149402982,-0.075111486,-0.0030955854,-0.0682979226,0.0145294443,0.066074267,0.0463328175,0.0041343835,-0.0017602595,-0.0046903333,0.0323604345,-0.0082792314,0.0580178648,-0.0726599023,-0.0964321792,0.0592342503,-0.0856896192,-0.0000139242,-0.0279955193,-0.0270229895,-0.0271729119,0.0541053601,-0.0196400527,-0.0032322053,0.0212826841,0.016293617,0.0414415263,-0.0162722748,-0.0479509793,0.0013415467,0.0083340425,-0.0459090099,-0.0219292194,0.0398544893,-0.0600825474,0.0326734707,-0.0007112727,-0.0151779475,-0.0764904469,0.0172602274,-0.0486444421,-0.0257844273,0.044758711,0.0813878477,-0.0295197181,0.0564880669,-0.0271630269,-0.1679700315,0.0190677252,-0.0155195249,0.1023653895,0.0196821261,0.0192368738,-0.0270703826,0.0127995461,-0.0417167619,0.0139178429,0.0315813534,-0.0289036483,-0.0340657867,0.072954908,-0.0421257913,0.0333875194,0.0100068273,-0.0607307591,0.0377560817,-0.0366016626,-0.0315349847,0.0011905429,-0.0415716656,-0.0734767988,-0.0487904325,0.0902582183,0.0511143394,-0.0129798995,0.0248920992,0.0153058264,0.080109641,0.0436211489,-0.0328056142,-0.0224334877,-0.0205615703,0.0385683812,-0.0758696869,0.3097238839,-0.0711162165,0.0033160052,0.066331394,-0.0640572608,0.0178423785,0.0022314498,-0.033575315,0.0456098393,0.0196421705,0.0143445637,0.0211180001,-0.0450119302,0.0568365194,0.0231120437,0.0705785677,-0.0442226119,0.0810848847,-0.0022832151,-0.095061101,0.0015776186,0.0331413709,0.0401788764,0.0156131424,-0.0001800821,0.1154262349,-0.0699454322,-0.0572120063,0.0780743286,0.0065325508,-0.0150383273,-0.0130694816,0.0275703594,-0.0338438116,0.0415048711,-0.0114634773,-0.0228517037,-0.0489287861,0.0443742909,-0.0326981284,0.0429785624,-0.0011253059,-0.0732491761,-0.1175054833,-0.1050615981,-0.0210755356,-0.0082121966,-0.0340153351,-0.0255849101,0.0069136913,0.065894857,0.0307804067,0.0351373963,0.0038989775,-0.0076788245,-0.0495790727,0.0120340139,-0.0090762516,0.0231141951,-0.0223100949,-0.052264411,0.0566511229,0.0104838647,-0.0666960478,0.0335290655,0.0437751412,0.0540754907,-0.0346533135,-0.0097977836,0.0520854332,-0.0127894683,-0.0279730614,-0.0121127423,-0.0245319046,-0.0271541514,0.0912807137,0.0199592505,0.0380162559,0.0151104201,-0.0195530877,-0.0139135234,0.0114050247,0.0277508851,-0.0053344546,0.0100714834,-0.0192135572,0.0380325653,-0.0183313061,-0.0460206978,0.0769373178,-0.0633725226,-0.0660540387,0.1062323973,-0.058078263,-0.057014551,-0.0156930927,0.0029127568,-0.0573680885,0.0058833291,0.0517654121,0.0037442176,-0.0029939092,-0.0374631844,-0.0896256268,0.0274640266,0.0804590806,0.0278137755,0.0543609634,0.0439408347,-0.0721111819,0.0063570379,0.0093957651,-0.0722144917,0.1333598942,-0.0506547131,-0.0140208043,0.0046350975,0.0188527238,-0.0001334144,-0.0044523356,0.0358728878,0.0346081443,-0.0163533501,0.0275479797,-0.2665844858,0.0062821051,-0.0543762334,-0.1087894961,0.0536313318,0.0179213192,0.0494529083,-0.0233098529,0.0093713207,0.0667182878,-0.017913498,0.003806574,0.0581394508,-0.0074004047,-0.0020057322,-0.0383514836,-0.0733583644,0.1013899222,-0.0085919583,0.0143850558,-0.0388516672,-0.0489284433,-0.0826537162,-0.0476488397,0.0192888472,0.0355221406,0.0995751396,0.1345744133,0.0253313109,-0.0127241826,0.0041916789,0.0861127675,-0.069832243,-0.0750925764,-0.0018349519,0.0371227041,0.0276989732,-0.0431761444,0.0259704199,0.0318452492,-0.0194712039,0.0186820254,-0.0093609076,-0.1102665812,-0.0228410792,-0.0105639715,-0.0956589356,0.0878086612,0.0092125684,0.0016172496,0.0533155203,0.0385836363,0.0279408153,0.0199971162,-0.0119324056,-0.0250365306,-0.0391286239,0.0489305072,-0.0298808478,0.0126336487,-0.0047824094,-0.0044078911,-0.0318139754,0.0196700506,0.0502493232,0.0465189368,0.0390594043,0.0107358722,-0.0465799756,0.0651126578,0.0048291273,0.0713080987,-0.0308140405,-0.0932846516,-0.0114412419,0.0246237218,-0.0232816096,0.0079188598,-0.0515909046,0.0100755552,0.0420338139,0.0010036759,-0.0206017233,-0.0326895081,0.0198536273,-0.0183586311,-0.0398503393,0.0267252922,0.0641575754,-0.0488765836,0.0277102813,-0.0182832219,-0.0047651497,-0.0038511329,-0.0367830507,-0.0138178812,-0.2277992964,-0.0066341613,-0.0151151745,0.0813750774,-0.0098102065,0.0007813521,0.0470795482,0.0628998429,0.016639566,0.008940516,-0.0221822653,0.0736520961,-0.0202783458,0.0014458619,0.035474062,-0.0851928666,0.0720083043,-0.0215886757,-0.0123910112,0.0353275724,-0.0474580377,-0.0638069212,0.0674652159,0.010031662,0.0660442188,-0.0112358266,-0.000016157,0.0070150765,0.0041061393,-0.0422695465,-0.0118245296,-0.0306479633,-0.0022587739,-0.0190974567,0.0163045414,-0.0254523009,-0.017247403,-0.04255246,0.0336909108,-0.0383746438,-0.0548082367,0.0169965159,0.094897382,-0.0167060848,0.075434342,-0.0004839846,-0.0435381308,-0.0078155389,0.0575728156,0.0378433652,-0.0230000187,0.0290913209,-0.0357556492,0.0004601715,0.0418382101,0.0152376397,-0.033438988,-0.0090973042,0.022156598,0.0357945599,-0.0039889151,-0.0241003409,-0.0259189047,0.0182730351,-0.0453781039]} 5 | {"point_uid":"887cd819-15f5-4c27-a17b-532fec485271","category":"politics","utterance":"they will save the country!","embedding":[-0.0256774742,0.0141905453,0.0243489128,-0.0009505684,0.1056153253,-0.0015386466,0.0012314731,0.0472766198,-0.0460716374,0.0304490738,-0.0309361238,-0.0263562966,0.0231178477,0.0247387588,0.0259321872,0.0106999008,-0.0615106635,0.0291435011,-0.122348763,0.0481879413,0.0240760222,0.0005990806,0.0044217086,-0.0154642565,0.0011507394,0.0225475486,0.0098570976,0.0253427476,-0.0066322996,-0.1308008134,0.0517668091,-0.0566392727,-0.0307399556,-0.0233601499,-0.0165799931,0.0101331854,0.0552908666,-0.0076723336,-0.0011434967,0.0277980398,0.0121163903,0.0160029121,-0.0067146881,-0.0418604873,0.0119199185,0.0141675994,0.0091117807,-0.0216338038,-0.0059441361,-0.0378443189,0.049813889,-0.002692342,-0.0593843274,-0.0815322101,0.0398363471,-0.0156557467,-0.0611272529,0.0361449085,0.0631288514,-0.0148628773,0.0454259701,0.0072324509,-0.1951951087,0.0204123985,-0.0395507403,0.0672801957,0.0201844666,0.0207884274,-0.0114441253,-0.0070666121,-0.0585616529,0.0170151778,0.0054063676,-0.0335790478,-0.0024866567,0.0665144026,0.0060841367,0.0081721563,-0.0544364303,-0.0346259065,0.0265450031,-0.0085453475,-0.0278823022,0.0418649353,-0.0428802744,-0.078029491,0.0035158044,0.029416725,0.0260218363,-0.0273901504,0.0403826274,0.0050574834,0.054805737,0.0393281914,-0.0579022169,-0.0039959839,0.0062432401,0.0319746546,-0.0861142352,0.3651871085,-0.0300880615,-0.004505876,0.0514877252,-0.0937907696,0.0290304031,-0.0245064795,-0.0264699887,0.0414458029,0.0063776579,-0.0011097707,0.0254205801,-0.0169069767,0.0616570488,0.0113189826,0.0279910173,-0.0137328953,0.0449132286,0.0159738753,-0.0852469355,-0.0393868536,0.0082909744,0.0576284751,0.0284117702,-0.044856023,0.0706822053,0.0206401721,0.0013569698,0.0656568259,0.0381375328,0.017326504,-0.009115559,-0.0292443857,-0.0424739793,0.0109669967,-0.0454547666,-0.0495492406,-0.0309151821,0.0079748109,-0.0866400674,-0.0084272651,0.0515838228,-0.0528403334,-0.0948111862,-0.1308666021,-0.0695607588,-0.0116578704,0.0335281193,0.0017475483,0.0173988175,0.0219348054,-0.0139561743,0.061784368,0.0234345309,0.0111676008,-0.0489093959,0.0515676774,0.004643078,-0.0033830549,0.0050373198,0.0156666972,0.0299637094,-0.0228145197,-0.059211202,0.009114054,0.0274497699,-0.0249927081,-0.0450668558,-0.0163437575,0.0309487395,-0.016371116,-0.0137625849,0.0202021468,-0.03614657,-0.0481678061,0.1143847778,-0.0015244988,-0.0094917007,-0.0029402608,-0.0108808605,-0.064580299,-0.0078368895,-0.0016647638,0.0184920728,-0.0010090786,-0.012498403,0.0469442643,-0.0588383861,-0.0435228944,0.0504371636,-0.0630996004,0.0103700552,0.1162808612,-0.0207705311,-0.0437235236,-0.0230051223,0.02370256,-0.1017242298,-0.0198038612,0.0206678119,-0.0146875503,-0.0712480247,-0.0531902947,-0.0404614769,0.0258134082,0.0824941397,0.016124215,0.0849084929,0.0350537635,-0.0224503875,0.017985234,-0.0002220275,-0.0449785627,0.1641060859,-0.0039662477,-0.0531038642,0.0632968992,0.0260586422,0.0068617719,0.0118227769,0.0199827533,0.0885062367,-0.0269957986,0.0184703302,-0.2780762315,0.0326591432,-0.0545902401,-0.0620899238,0.0651342645,0.007802845,0.0270047039,0.0008807064,0.0239544883,0.0689552724,0.0349243768,-0.059519507,0.032086961,0.0696570277,-0.0174360219,-0.019921165,-0.0646845028,0.0783072487,0.0165831354,0.0165691096,-0.0165059101,-0.0109621668,-0.0671457425,-0.0048931064,0.0551811866,0.0024511551,0.1075436026,0.0676185042,0.0385162793,-0.0244407337,-0.005896281,0.073309198,-0.0383987091,-0.1302764416,0.0214045309,0.0486554876,-0.0052927737,-0.003374418,-0.0285718478,-0.0088426601,0.0566136204,0.0581625216,-0.0285822637,-0.0695633963,-0.0200791173,-0.0195936523,-0.0974754766,0.0730013028,-0.0280620269,-0.0390378125,0.019008277,0.0052576391,0.0573851243,0.0022292738,-0.029379176,0.0378832072,-0.039440237,0.0836920068,-0.0270201918,0.0508957505,0.0011578978,-0.0062460452,0.0048610084,0.0225894246,0.0499686413,0.0004257706,0.0271725841,0.0223320704,-0.0407151692,0.0547144152,-0.0171353612,0.0219041239,-0.0549295582,-0.0728703588,-0.0090187518,0.0049647051,-0.0127819004,0.0360500924,-0.0212050173,-0.0128382267,0.0581108741,-0.0313062668,-0.037189085,0.0088732475,0.0424279422,0.0476856977,-0.0102828788,0.0338684395,0.027586123,-0.0095136939,0.0217963606,-0.0340120047,0.0251298342,-0.0013183029,-0.0308989268,-0.0325632878,-0.2536266744,0.0489706211,-0.0109159881,-0.0142806824,-0.0013486604,-0.0321135074,0.0204790998,0.0714008063,-0.0284702033,0.0506329164,0.0098469993,0.0646834671,0.0275021307,0.0132629396,-0.0053286403,-0.0436409265,0.0679145604,-0.0186393093,-0.0097422469,-0.0365915187,-0.0324015692,-0.0366353914,0.087768957,0.0019666627,0.0540439487,-0.0016164928,0.0070027355,-0.0189465526,0.0032922814,0.0162847824,-0.009441006,-0.0001772085,0.0167311784,-0.0183489285,0.0089072753,0.0047554374,-0.0460969843,0.0172309186,0.0290814973,-0.0253273733,-0.0716200769,0.0218836591,0.0925518647,-0.0351159275,0.0298446901,-0.0181752369,-0.0423582941,-0.0146177718,0.0409666933,0.0292719174,-0.0102841351,0.0343608819,0.0076987725,-0.0607996471,0.0055856011,-0.0133848432,-0.0143618016,0.0155979376,0.0482243709,0.0518812127,-0.0293837283,-0.0975788981,0.0335687324,-0.0057573551,-0.0020856501]} 6 | {"point_uid":"b9784f9c-ace9-4939-87d3-83e28dc44b5e","category":"chitchat","utterance":"how's the weather today?","embedding":[-0.0280579049,-0.0897267386,-0.0084698768,0.0247592013,0.0567495301,0.0026388939,0.040112745,-0.0159150194,0.0136502171,0.0272733141,-0.0416154899,-0.0832074061,0.0158200674,0.0360628441,0.0261075329,0.0356682725,0.0685096532,-0.1071911156,-0.0521458089,0.0500642881,-0.0847136751,0.0141714457,-0.0633273199,-0.0417503901,0.0028977226,0.0446688123,0.0286176689,0.0269938949,-0.0373868681,-0.0075647971,-0.0433912985,0.0073019029,0.0053688218,0.0169090293,0.0425154716,-0.0349331051,0.0257866029,-0.0128581896,-0.001773735,0.0097830193,0.0127643151,-0.0135145811,-0.0874955803,-0.0371211618,0.035246931,0.0054983976,0.0169183724,0.0898080841,0.0520443767,-0.0076333177,0.0128446789,0.0247115679,-0.0259553753,0.0526002161,0.0642124563,0.0813168809,0.0244979747,-0.0164966527,0.0334654711,-0.0138788363,0.0193158146,0.0223769173,-0.1507311612,0.0856877267,0.0032523312,-0.0055467323,-0.0680792779,-0.0134624792,-0.0093730083,-0.0263193846,0.0593904965,-0.0010766129,0.0350942761,0.0246525332,0.0133516556,-0.002106705,-0.0060381526,-0.0008379397,0.0245572533,-0.0604744889,0.0102851111,-0.0379654393,-0.0373930559,0.0017193359,-0.0067292033,0.03544043,-0.0173435193,0.1310039312,-0.0038812172,-0.0470975041,-0.0500973426,-0.0115078902,-0.0171820577,0.0257638618,-0.0277609639,0.0428480282,0.0122925127,0.0215000436,-0.0084170671,0.3108131886,-0.0773211941,0.0386258215,0.0385585129,-0.0108395461,-0.0004832834,-0.0098672425,0.0006907108,-0.0710165277,-0.0401327796,-0.057959713,0.0153126949,-0.0229437184,0.0830397829,0.018040901,0.0436135493,-0.031368766,0.1485065073,0.0125675527,0.0357586741,-0.000920759,-0.0114021506,0.0254629944,0.0082319137,0.0712406188,0.1141073406,-0.0660503805,0.0462383851,0.0915066227,-0.0109404521,0.0373174548,0.0469016396,-0.0479316749,-0.0182435475,-0.0431044437,0.0303492658,0.0023623484,0.0104222381,0.0044639781,-0.0243241712,0.0223367568,-0.06159072,-0.0859751925,-0.0345036983,-0.1218965724,0.0168537311,0.0175088681,-0.0645106882,0.0215657037,-0.0063289683,-0.0499162786,-0.0681510642,0.0273846742,0.0072914581,-0.0565535091,0.0528784767,0.0017889822,0.0053477837,0.0195829496,0.0239636824,-0.0348729566,0.0599225722,0.0131995082,-0.0615563169,-0.0505822413,-0.0475953817,-0.0404493213,-0.023250429,0.0278553385,-0.0021114233,0.0225930475,0.0440259911,0.0599459,0.0059649171,0.042521812,0.0888061598,0.0258265678,0.0659739748,-0.0020146878,0.0272164289,0.0081403721,0.0002075551,-0.0239514578,0.0313893892,-0.0164143182,-0.0161157958,-0.0121672209,-0.0230148658,-0.0138531299,0.020114867,-0.0115537196,-0.0043639927,-0.1322663724,0.0375158601,0.0485740043,-0.0901819244,0.0343089476,0.0299065709,0.0200809371,0.031500686,0.0225233342,0.0104099847,-0.0628635287,0.0400064327,0.0103714634,0.0245771557,0.0056734201,0.0299538374,-0.0095906202,-0.0018039916,0.0167071223,0.0313630961,-0.0548363961,0.1008633077,-0.038640894,-0.0174373612,-0.0694265664,-0.0038037191,0.0240544584,-0.0117665324,0.0060492731,-0.0324740671,-0.0362112708,0.0107387649,-0.2237061411,0.028329812,0.0084071299,-0.0488791503,0.0972968787,-0.0680613443,0.0464359224,0.0204490796,0.0997335389,0.0460708998,0.0223048814,-0.0847961232,-0.0034141713,-0.0984428376,0.0175241698,0.0054496634,0.009734517,0.0208723973,0.0604406334,-0.0371414088,-0.0021848008,0.0538413078,-0.0910690278,-0.081565097,0.024951024,-0.0465244651,0.0874948651,0.0609136894,0.0322991572,-0.0390553586,0.0338427015,-0.0357735902,0.0276501216,-0.1641675532,0.0562406741,0.0072899,0.0133792134,-0.0042187255,-0.121860154,-0.0005870692,0.0143342139,-0.0209341906,0.0017576662,-0.069992587,-0.0132066207,-0.0410278775,0.0550010242,0.047383517,-0.0766866058,0.0003911541,-0.0378711149,-0.0633845255,0.0371553414,-0.0132112568,0.028348783,-0.0224354565,-0.0534721874,0.0081163663,0.0119318403,0.0142648546,0.0063883862,0.0510603972,0.0174550097,0.0306063443,-0.0463259146,0.0828236863,0.0141228642,-0.05291453,0.0043689436,-0.0183983818,-0.0425685272,0.002090031,-0.0465844423,0.0057280995,0.0116157271,0.0382020213,0.0626143366,0.0618492924,0.0276358742,-0.0369123928,0.0598842427,-0.0581195652,0.0843251124,0.0000894923,0.0425401554,0.0102578504,0.0354673788,-0.0239025317,0.0068299188,-0.065581128,-0.0470664464,-0.0494921133,0.0115778809,-0.1347809285,0.1033041775,-0.080985114,-0.1889504343,-0.0228005946,0.0157734491,-0.0318868384,-0.0283288546,-0.0502831452,0.0212110262,0.0389370508,-0.0927666202,0.0554744117,0.0328585133,0.0803209618,-0.0106582306,-0.0173899326,-0.0273137446,-0.0423626415,-0.0413649939,-0.0549060218,0.0068300371,0.0333917253,0.0085059134,0.0054444349,0.0546787418,0.0022562454,0.0964370146,0.1011111513,-0.034887556,0.0442447625,0.0071383975,0.0474796519,0.0652627349,-0.0568757504,0.0414744504,-0.0614265874,0.0341103971,0.0111023281,-0.0448963717,0.0401077121,0.0290822517,-0.0273752473,0.0007545291,0.0908913985,0.0002492291,0.0369924158,0.0546894446,-0.0197395273,-0.0062948945,-0.0553076975,-0.0440504253,-0.007539962,0.0096509801,-0.0006920372,-0.0078138821,0.0011208754,-0.0026363358,0.0271349996,-0.0185785368,-0.0541888624,-0.026015481,-0.0510912761,-0.0507781133,-0.0495537072,-0.009260566,0.0037503452,0.0142982602]} 7 | {"point_uid":"8453a119-eff9-4473-bbb9-359adf9bf4c0","category":"chitchat","utterance":"how are things going?","embedding":[-0.0267448649,-0.0656731501,0.0310572051,-0.0504162349,0.0025865843,-0.0267256293,0.0704843327,0.008889799,-0.0010499306,0.0474731773,0.0113265002,-0.0381700732,0.0452045612,0.0078710746,0.0165771451,0.019937614,0.0082062911,-0.1576804221,-0.1094623953,0.0206515007,-0.0815895274,0.0214376226,-0.0474924818,-0.0724651143,0.0099053318,0.0306781288,0.0397550352,0.0029883659,-0.0467326082,-0.0432412997,-0.0210912097,-0.0124294236,0.0362588353,-0.0060028997,0.0386098959,0.0248332918,0.0333337635,-0.0253858436,-0.0132284472,0.0081465682,0.0430429392,-0.0446915366,-0.0764595494,-0.0928543508,0.043599166,-0.0386474803,0.0300283674,-0.0212640446,0.0134611269,-0.0311828535,-0.0452252477,0.0064888443,0.0419152416,0.0060872291,0.0093128644,0.0596257932,0.0897325352,-0.0184355937,0.0759659261,-0.0167074278,0.0226863101,0.0177874882,-0.1175124794,0.0918270573,0.0000089775,-0.0320399739,-0.0561140887,-0.0215708595,0.0066564241,0.048538059,0.0270622969,-0.0378841907,0.01630315,0.0573785082,0.0527244247,-0.002829775,0.0602291152,-0.0376934819,0.0370865837,-0.0288937036,-0.006659193,-0.0573813207,-0.0049196263,0.0413029604,-0.0148106795,-0.0126713701,-0.0417639762,0.116260536,-0.0098099736,-0.018343471,-0.0282346718,0.0368495062,0.0250364374,0.0509874821,0.0005919152,-0.0332358889,0.0047253598,0.0059395642,-0.0589269549,0.3359591365,-0.0440682545,0.0320522189,0.1196938306,-0.0088198436,-0.0195676032,0.0001379701,-0.016655976,-0.058331605,-0.0108331321,-0.0434697382,0.0069781709,-0.0101122828,0.0286256317,0.0104186321,0.0060882419,0.0220731627,0.0409971513,-0.0021337403,0.0504216515,-0.0570787862,0.0609696321,0.0493532084,-0.0140753668,0.0052923975,0.1069830582,-0.0519621558,0.0756761804,0.0994120464,-0.0056599956,0.0190518089,0.0517402515,0.0152363013,-0.0666297674,0.0077924067,-0.0287803765,0.0044001816,0.037071839,0.0035557307,0.0205039717,0.052233763,-0.0423611477,-0.0906807929,-0.0312023796,-0.1962916702,0.0026525951,0.0492893457,-0.0333428793,0.0151069826,0.035258621,0.0073905238,-0.0522451587,0.054177206,0.0498872548,-0.0699307397,-0.0065055741,-0.0002637577,0.015702337,-0.0002070493,-0.0192574412,0.0241879169,0.026300814,-0.0111209704,-0.0261774454,-0.0023150425,-0.0040821424,-0.0534745418,-0.0356554501,0.0261929631,0.0451418012,0.0209836643,0.0154360468,0.0741372705,0.0110987388,-0.0015813094,0.0880013704,0.0044870144,0.0590183027,0.0010368101,-0.0237600617,-0.0259064436,-0.017344445,0.0537608117,-0.0008408306,0.0008478597,-0.0172555912,-0.0545690693,0.0014237603,-0.008851246,0.0251993556,0.0006251704,-0.0130242128,-0.0831224918,0.0046209199,0.0592571199,-0.0084514469,0.0090043861,0.0176649075,-0.0144890184,-0.030447308,0.0345154926,-0.0028382244,-0.0332668573,0.0089714322,0.0504162721,0.0621149503,-0.0077281753,-0.002555582,0.0125482492,-0.0065233069,0.0489038043,-0.0229709223,-0.0904453695,0.1327182353,-0.0514547005,0.0013581468,-0.0830055326,-0.0241542924,0.0328486077,-0.0623494796,0.0513085276,-0.0212774836,-0.000720086,0.0381173976,-0.2936772704,0.0685151443,0.042723842,-0.0297952462,0.0574672632,-0.0244986601,0.0436320677,0.0097922692,0.044546172,0.0636403561,-0.0164066963,-0.0633149967,0.0239738636,-0.0478017181,0.0285439044,-0.0302612912,0.009976388,-0.0212630387,-0.0058354693,0.0132626044,-0.0177016407,-0.0008987507,-0.0318748541,-0.0530005693,-0.0106146606,-0.0494335964,0.1238831505,0.0841699541,0.0293323044,-0.0246970262,0.0125133283,0.0199024808,-0.0186201204,-0.1807579696,0.1122283936,0.0691051781,-0.0291850511,-0.0262666121,-0.079934217,0.0017429239,-0.0066430867,0.025956016,-0.0189580116,-0.0331985429,-0.0430740118,-0.0477479696,0.0221343134,-0.0450276583,-0.045983173,0.0153452065,0.0167668238,-0.0464767776,0.0389309078,0.0115923202,-0.0254180059,-0.0040303343,-0.0204494502,-0.0438803099,-0.0202980116,0.0428723432,-0.0208215714,0.0586090572,0.0350036882,0.0315785222,0.0187847745,0.0552722774,0.0189000666,-0.0067859362,0.0238367897,-0.0367336906,-0.0193334967,-0.0303527787,-0.0323251896,-0.0269041732,-0.0110733844,0.038622953,0.0041121212,0.0734348297,-0.0121189244,-0.0090464707,0.0569361858,-0.0526702888,0.0239767861,-0.0174269881,0.040333502,0.0031792638,-0.0044862707,-0.0617280491,0.0384291783,-0.0268258248,-0.0231348779,0.0001345725,-0.0227499753,-0.1103131846,0.0164704956,-0.038406007,-0.1874247044,0.0020612974,-0.0014629886,-0.0046650772,-0.0704243928,0.0063563674,0.0204014573,0.1169699281,-0.0800665468,0.0531412102,0.0417733379,0.0664323866,0.0083666602,-0.0339994393,-0.0127409101,0.0013271562,0.0353224836,-0.1116705164,0.0272516776,-0.0100398948,0.0347069949,-0.0342728347,0.0789454505,0.023649754,0.0935122147,0.0376919061,0.0234580301,0.0315220319,-0.0032559568,-0.0110275345,0.0214903913,-0.0112707615,0.0298399609,-0.0435093604,0.0149653144,-0.0317618884,-0.0772711188,0.0543110296,0.0271660648,-0.0045628147,-0.0302620679,-0.0068557886,-0.0187351163,0.0134184519,0.0717949197,-0.038456101,-0.0147114815,-0.0383438803,0.0171102397,0.0145335617,-0.0215058308,0.0070498479,0.0120537831,0.0228567086,0.0213107541,0.0387595408,-0.0402518362,0.0079566082,0.0154077904,-0.0359235667,-0.077689372,-0.0349712335,0.0380203091,0.0160830822,-0.0134153515]} 8 | {"point_uid":"82dafcc6-b4eb-4ea1-967c-5d21453d881c","category":"chitchat","utterance":"lovely weather today","embedding":[-0.0086631961,-0.0552479587,0.0361469612,0.0181038249,0.0619851761,0.0054919501,0.0177799203,0.0115334466,0.0262151305,0.0013970356,-0.0769088715,-0.0689348876,0.0309626125,0.0679482296,-0.0178759359,0.0315710679,0.0738464147,-0.0331999697,-0.051181078,0.0460228771,-0.0220417231,0.008208286,-0.0314260125,-0.0436864421,-0.0101976357,0.0228289068,0.0260233879,0.0191476401,-0.0317733064,-0.0476001389,-0.042753078,0.0123775508,0.0130432844,0.0056602787,0.0256777182,-0.0151662547,-0.0042484538,0.0174680594,-0.0510878973,-0.0115456088,-0.0100371176,-0.0566673204,-0.0882606581,0.0182540584,0.0031225879,0.0075577837,-0.0045381547,0.0649879724,0.0930117741,-0.0166769177,-0.0042419811,0.0001619728,-0.0256609563,0.0170144141,0.0655910671,0.0923294947,0.0516437441,-0.0019429909,0.0257512797,-0.0168406405,0.008458537,0.0666695684,-0.1344975382,0.0602848604,-0.0184318628,-0.0444732532,-0.0435755998,-0.0061520832,0.0076105502,-0.0189681463,0.0241238158,0.0336877331,0.0510270745,0.0468816198,0.024327388,-0.0122932941,-0.0187057517,-0.0307155661,-0.0328809544,-0.0662960559,0.0627937615,-0.0339009464,-0.0149505101,-0.0174377225,0.0118907522,0.0258716885,0.0012867394,0.034335807,0.0452181399,-0.0187250972,-0.0537541211,-0.0708745271,-0.104772903,0.0290340278,-0.0193459,0.036908593,0.0228268597,0.0459744781,0.0545740686,0.3667625487,-0.1064295769,0.067008175,0.0114707453,-0.0095996587,-0.0080183288,0.0074715642,0.0121652586,-0.0423851274,-0.0424223877,-0.0518426821,0.0474513844,-0.0369914733,0.0653861761,-0.0135946227,0.0029919827,-0.0353127792,0.108885169,0.0145930387,-0.0018033143,-0.0229545776,-0.0384115167,0.014854718,-0.0013530073,0.0543615669,0.0588978231,-0.0197329801,0.0425557606,0.0765537396,0.0069193556,0.0592491813,-0.0047123437,-0.0132679958,0.0112095876,-0.0596451685,0.0470378734,-0.0047103455,-0.0064965189,-0.0125263026,-0.0020002872,-0.0016168995,-0.0262500811,-0.1157381833,-0.0297847968,-0.1185346618,0.0550783202,0.0006612409,-0.051309716,0.0462798849,0.0042131278,-0.0615395643,-0.0558337532,0.0312516652,0.0126119647,-0.0198901854,0.0498087518,0.0217774305,0.0006031204,0.077510573,0.0380088948,-0.0162960794,0.0682408735,0.0343776643,-0.0204131324,-0.086392507,-0.0575236119,-0.0668745786,0.0096302945,0.0156550072,-0.004920681,0.0070165526,0.002844671,0.0378691219,-0.0512727387,0.0244005136,0.1214745268,-0.0072682444,0.0414258242,0.0160785802,-0.0163143296,0.0341693237,0.0177863073,-0.0149624776,0.0052407463,-0.0112779513,0.0306329671,0.0050346544,-0.0134504875,-0.0502251424,-0.0258264095,-0.0077122799,0.0026339784,-0.0730195045,0.0444840565,0.0117946761,-0.06225821,0.0219527837,-0.0261995979,0.0187067296,0.0010978736,0.0359423757,0.0464427955,-0.0559021384,0.0147905732,0.0167585835,0.0382896215,-0.039792452,0.0599298477,-0.0030162786,-0.0046829372,0.0213616248,0.0213875864,-0.0166029148,0.1382392943,-0.0138291949,0.0051579578,0.0006141526,-0.0134467278,0.0705003887,0.0088749519,-0.0002563544,-0.000723499,-0.0383330099,-0.0635046512,-0.2565392256,0.0233410448,0.0491953939,-0.085918583,0.0393679924,-0.0302713048,0.0189400557,0.0046634004,0.0803361014,0.0142247798,0.0580256172,-0.0987936333,0.0106538078,-0.0634357929,0.0409851745,0.0158536956,0.0315327495,0.0287138689,0.0289808512,-0.0322859287,-0.008997404,0.0245285425,-0.0616388321,-0.0616325289,0.0273464527,-0.0366599374,0.1451385021,0.0418517664,-0.0134215392,-0.0280326661,-0.018306721,-0.0850472748,0.0114480387,-0.1283779591,0.0142060993,0.0271853171,0.061832495,0.0082311956,-0.1187620237,0.0206627622,0.0554258749,0.0437471308,-0.0077902358,-0.066226393,0.0185680073,-0.0663793832,0.0334791504,0.0463562943,-0.0504981056,-0.0578377135,-0.0130694639,-0.0227159057,0.0707749724,-0.00470101,0.0285711735,-0.0497466959,-0.036843881,0.0292812455,-0.023900399,0.0285491757,0.0111402059,-0.0047724145,0.0173319094,0.0005760132,-0.0086774724,0.0524600595,0.0089395661,-0.0432865806,0.0046587903,0.0271654837,-0.016209485,-0.059874028,-0.0250037629,-0.0364190675,0.0310861412,0.0170976892,0.0112357922,0.0524995439,0.0138319833,-0.0407535061,0.067223452,-0.0478674397,0.0577720106,0.0467562489,0.0298043098,0.0253963806,0.0250882972,0.0296249315,0.0182674043,-0.0644199401,-0.0541667305,-0.0144012319,0.0213770811,-0.0739952549,0.1043888628,-0.029665051,-0.2512119412,-0.0122626675,-0.0502462611,-0.0467594638,-0.0287884735,0.00175793,0.0219497792,0.0327309594,-0.093031317,0.0135901114,-0.0190127324,0.0468446016,0.0023352681,0.0133452965,-0.0176268481,-0.0102972593,-0.0342226215,-0.0124606164,-0.0193957929,-0.0171935782,0.0225896239,0.0281017032,0.1717540175,-0.0164119769,0.0707629025,0.0557770915,-0.0306799412,0.0139943417,-0.0362587385,-0.0009453343,0.0232895855,-0.0607572235,-0.0043594409,-0.0749581382,0.0086414302,0.0459943712,-0.0176215563,0.0208122414,0.0360193551,-0.0512737222,-0.030768536,0.0907877609,-0.034304861,0.0234221779,0.0296109188,-0.067823343,0.0129762385,-0.0025940666,-0.0046242862,0.0224997662,0.0138417641,0.0068998346,-0.0590383001,0.0085818367,-0.0011167285,0.0372307673,-0.0405185185,-0.0356763341,-0.0119798426,-0.0034822088,0.0133621646,-0.0657942444,-0.0227787811,-0.0060689705,0.0094807539]} 9 | {"point_uid":"7f2ad3ce-4505-4d3b-89c1-178abc1aee80","category":"chitchat","utterance":"the weather is horrendous","embedding":[0.0374679416,-0.0004074696,0.0462700427,0.0438011698,0.1382139921,-0.0243258867,0.0383215807,-0.0407126471,-0.0044702156,-0.0136078727,-0.0533559583,-0.0362590067,0.062744461,0.0807114691,-0.0443023145,0.0097414088,0.0204243641,0.0116440002,-0.0137081807,0.0644979626,0.0251919087,0.005628156,-0.0264649503,-0.0515545532,0.0031230722,0.0199476015,-0.0056937453,0.0759153739,-0.0477657616,-0.0297462717,-0.022730412,-0.0407222137,0.0302857738,0.0142210172,0.0188636258,0.0199112184,0.0247178562,0.0098411907,-0.0206958409,0.0240282398,0.0063646301,0.0332197025,-0.0469271466,-0.076481007,-0.0061680442,-0.0440809354,-0.006797378,0.0526487902,0.1117959619,-0.0710012615,-0.0182852689,0.0004655354,-0.0370314419,0.0499038659,0.0666937754,0.0189921763,-0.0082597109,-0.0042827851,-0.0142306546,-0.0148420557,-0.0198655501,0.0265444759,-0.1029274538,0.0105540231,0.0665836036,-0.0140541298,-0.0287362207,0.0225207508,-0.0089448085,-0.0338922106,-0.0213563014,0.0010661928,0.0499727204,0.0518112592,0.0068722693,0.0000336057,-0.0924069732,-0.0113112368,0.0008264303,-0.033229053,0.0466176085,-0.0095037306,-0.0008749538,-0.0112799201,0.0500071943,-0.0468543954,-0.0311567374,0.0294804592,0.0256533138,-0.0119331954,-0.0176721346,-0.0583692938,-0.0154557535,-0.0068675014,-0.0063261841,0.0349700823,0.028463712,0.0048958259,-0.0519622564,0.3769171834,-0.0638828129,0.0133386236,0.0415660441,0.0072708298,-0.0260941982,0.0119301006,0.011024842,-0.0672680661,-0.0710041523,-0.0114364773,-0.0327921808,-0.0587925315,0.0027942082,0.0109717119,0.0230157729,-0.0871059299,0.0545825586,0.03242651,-0.0661322623,0.0414390415,-0.0132007571,-0.0055977097,0.03064771,0.1061812416,0.0725423321,-0.0426843427,0.0185089596,0.1304356158,0.0138138682,-0.0200357027,0.0226826873,-0.0353978947,0.0231179856,-0.0003159401,-0.0052004987,-0.0320204422,-0.0430664942,-0.002439446,0.0045170095,-0.014375113,0.0263997652,-0.1167848259,-0.0402310081,-0.0589521937,0.0318322442,-0.012442233,-0.0602883473,-0.0037267378,0.0109580969,-0.0498720817,-0.0283210315,-0.0130880373,0.0604210831,0.0114887916,0.044122152,0.0077155163,-0.0078001558,0.0277038179,0.0357494466,-0.0161225591,0.053609319,-0.0080610774,-0.0309380032,-0.0439702272,0.0138660222,0.0890330747,-0.0192058627,0.0227672346,-0.0065985699,-0.0022167489,0.0198052134,-0.023995094,0.0046429536,0.0733784139,0.1136032343,-0.0111430772,0.0166332424,0.021538781,-0.0059303716,0.0084619708,0.0051941266,0.0510572083,0.007229507,-0.000381183,0.0774565786,-0.0074711675,-0.0512608439,-0.0317146406,0.0198071282,-0.0010452099,-0.0228959955,-0.063582249,0.0469880328,-0.0635657012,-0.0216596089,0.0350956209,-0.0197347868,-0.0239099488,0.0490634665,-0.0285844896,0.0463604257,-0.0529354811,-0.0094606718,-0.0252604168,0.0689359829,0.026432693,0.0383006744,-0.0529925823,-0.0018706712,0.0130554521,0.0431186929,-0.0522702336,0.1012094691,-0.0270666257,-0.0054371911,0.0042579668,0.0225892905,0.0188514758,-0.0177832879,-0.0124996444,0.0054390221,-0.052119337,0.0203616433,-0.3000268936,-0.0228318535,0.0002055983,-0.1034622639,0.0169455986,0.0095304409,0.0262632165,-0.059130732,0.0633295923,0.0643859655,0.0748248622,-0.0823960528,0.044798363,-0.0156922787,-0.0402710475,-0.0057423697,-0.0466823727,0.0969537795,0.0054994049,-0.0078996206,-0.0519566126,0.0450011156,-0.0782465935,-0.0710909292,0.0123132542,-0.0327358469,0.1850935072,0.0210135505,0.039576441,-0.0307487771,0.0139760962,-0.0239322223,0.0320893899,-0.0768643245,-0.0021678198,-0.0135374675,0.0800050423,-0.0236589424,-0.0800851136,-0.0232109539,0.0038248631,0.0507150181,-0.0020984323,-0.0054184678,-0.0458779857,0.0407236032,-0.0127818026,0.0805749074,-0.0665803179,-0.0136078866,-0.0035794885,-0.0357984006,0.06192955,-0.0030778577,0.0471118353,-0.0439312048,-0.0462539978,0.0385584943,0.027959086,-0.0097579984,0.0783051327,0.0065614367,0.0654569417,-0.0563809127,-0.0175504312,0.0506546758,0.0133024473,-0.0814568102,0.0438401215,0.0333112143,-0.0056403815,0.0248953439,-0.0268890038,-0.0700220093,0.0185872,-0.0017832794,-0.001498531,0.0128738834,-0.0175541826,-0.0074358243,0.0478912331,-0.0071438397,0.0026199513,0.0350122675,0.0156755969,-0.0092143426,-0.0195003226,-0.0145004615,0.0245728549,-0.0291244444,-0.0259473398,0.0158944391,-0.0127469972,-0.0169330444,0.0340155177,0.0137058459,-0.2621229291,-0.0315969735,-0.0242132917,-0.0171763413,-0.0110885892,-0.0549042113,-0.0836824477,0.0618449785,-0.0337540507,-0.0247169118,0.0176347587,-0.0104626054,0.0009260662,-0.0315843709,0.053933505,-0.0408220217,-0.0391098037,-0.0063763415,0.0442823209,0.0191334989,-0.0094015868,0.0527907573,0.1425997168,-0.0502522811,0.0307665076,0.0489497669,-0.0337700248,-0.0012579603,0.0553640015,-0.0029377802,0.0239874516,-0.0184782296,-0.0048394636,0.0194259901,-0.0263427943,-0.0474146381,0.0063949856,0.0095536644,0.0412228368,-0.052178856,-0.011464905,0.0685772598,0.0873834342,-0.0156751387,0.0850305036,-0.0254390053,0.0184357297,-0.035907235,0.0051092212,0.0362909548,0.0101920348,-0.0039323745,0.0029585049,0.007899601,-0.0051303608,0.0017303668,-0.0739591122,-0.0344787128,-0.0146511532,-0.050857842,0.0249640066,-0.0350264944,-0.0967245921,-0.0345107205,0.0166568253]} 10 | {"point_uid":"9d7d61c1-a922-456c-913f-3c3a51beb8aa","category":"chitchat","utterance":"let's go to the chippy","embedding":[-0.0298668183,-0.0988231897,0.0528200008,0.0019713473,-0.0217243154,-0.0278001651,0.0777620822,0.0310453754,-0.0004007592,-0.0197807066,-0.0026357123,-0.0794788674,0.0112316785,-0.0518640541,0.0389108956,0.0273486413,-0.0137861967,-0.0041094502,-0.0794451833,-0.0095991157,0.0313442685,-0.0231612418,-0.0239012185,0.0071359891,-0.0250055362,0.021139184,0.0058091707,-0.0446994565,-0.145997569,-0.0620094351,0.0619494505,0.0522313677,0.0336690024,-0.0316782407,0.0126643833,-0.0122830337,0.0681053773,0.0176313613,0.0271156151,-0.0021284742,0.0439253636,-0.0123728849,-0.0349714383,-0.0004760525,-0.0110314302,-0.0162170436,-0.0041238591,0.0239469316,0.0532449409,0.0034364685,-0.0454102419,0.0144435428,-0.0384697914,-0.0309385676,0.0300827976,0.0840783194,0.0584872738,-0.0221267249,0.0616178773,-0.0532135218,-0.0140361991,-0.0191112179,-0.1268004328,0.0678306073,0.0509188138,0.0101638474,-0.0119990511,0.0717739016,-0.0141505264,-0.0084570888,-0.0210386757,0.0330940001,-0.0259229802,0.087132737,-0.009370978,-0.0108883381,0.0193523467,0.0186841879,-0.0223912727,-0.0149359712,-0.0308208466,-0.0828681067,-0.004473934,0.0297700316,-0.0004598265,-0.0153176142,-0.0193593912,0.0397734605,-0.0002897182,-0.0169054344,0.0176572409,-0.006391983,0.0060461382,0.0296121575,-0.0425402634,0.0265578162,-0.0028607321,0.0062371497,-0.0082403151,0.3071676493,-0.0348868556,0.0580457859,0.0223991536,-0.0415191315,-0.0429677144,0.0388610959,0.0259498227,-0.0458750986,0.0789356157,-0.0364027359,0.04020679,0.0505930819,0.0679133311,0.0292474609,0.0163381472,-0.0138412863,0.0551655702,0.011858182,-0.0031750079,0.0030987223,0.0254180543,0.0096042631,-0.0424508229,0.0128227798,0.0449814424,-0.017889915,0.007347608,0.1518922597,0.0283265691,0.041278597,0.0068973373,-0.0302793644,0.011365965,0.0468490273,-0.0094018821,-0.0203835405,-0.0101633696,-0.0189146232,0.0502396002,-0.0566972494,0.0539490655,-0.1018694714,0.0025784788,-0.1367856711,0.0470274054,0.021097837,-0.0096785929,-0.0853170827,-0.0252414513,-0.0172280334,-0.0430498049,-0.0662982315,0.0424835868,0.0060983831,-0.0408841446,0.041925814,0.0244917404,0.0247750748,0.0036894667,0.0453521088,-0.0310650021,-0.0006799411,-0.0191741213,-0.0098816464,-0.0153361224,-0.1072502583,-0.0458864309,-0.0097557278,-0.0378496833,-0.0229054037,0.0308833532,0.0353899747,-0.0491010286,0.0599255413,0.0897580236,0.0414436609,-0.0695182234,0.0005912894,0.0051376116,0.0348797478,0.0051399767,-0.0472812243,-0.0368735306,-0.0380355008,0.0094814915,-0.0475023836,0.0071408744,-0.0248905644,0.0263961889,0.0202665385,-0.0368160382,0.0215532407,0.0146315806,0.0366797298,-0.0620502755,-0.0694921017,-0.046006538,-0.021935543,-0.0062271529,-0.0273359474,-0.0624704547,-0.0355921946,-0.0691559762,0.0665108562,0.065446429,-0.0079409862,0.0267349314,-0.0617464706,0.0639141202,0.0706961602,0.0060433694,-0.0368426777,0.1208853871,0.0402971804,0.0159986615,-0.0077059143,0.0104399268,0.0059358282,0.0067598294,0.0297126602,-0.0173687469,0.0442246534,-0.0142712761,-0.3174833059,0.0280375294,0.0218722653,-0.0148306349,0.0619898662,0.0272152852,-0.0224666186,-0.0152635435,0.0134239364,0.0300611239,0.062519297,-0.0381052159,0.0219357628,0.0345100239,-0.0162949357,0.0069477269,-0.0341924205,-0.0062726554,0.0315622464,-0.0263892282,-0.0271380711,0.0077040927,-0.067429252,-0.0833001733,-0.0012499673,0.0325740539,0.1784488261,0.1141135991,0.0160162654,-0.0211213883,0.0112676127,0.023267379,-0.0012709367,-0.0429302379,-0.0354719684,0.0248845611,0.0914729014,0.0145491548,-0.0516795442,-0.0581891946,-0.0117503209,0.0292551275,-0.0159537345,-0.1559960097,-0.0137800071,0.0204054657,-0.0209211241,0.0228112377,-0.0241678972,0.0312260091,0.0532678366,-0.0403459221,0.0114902621,-0.0017030752,0.0350657441,-0.0414514467,0.0336746648,-0.0193326529,-0.0103478348,0.0843016654,-0.0281946585,-0.0334423408,-0.0288467538,-0.0312991142,0.0242728703,0.0163819399,-0.006772236,-0.0206595175,0.0166082028,-0.0024487874,0.0253077503,-0.0569354147,-0.0112568624,-0.0337936431,0.0295888148,0.0214074142,0.0602775589,-0.0196248889,-0.0186583102,-0.0202836916,0.0674005523,0.071394138,0.0340791531,-0.0142485965,0.0037295388,-0.0150058866,-0.0383494645,0.0406856798,-0.0000510862,-0.0239626616,-0.0126242572,-0.006541234,-0.024963662,0.0332739912,-0.0304414183,0.0204715468,-0.2966176271,0.07114847,0.0270737056,0.0152418008,-0.023827672,0.0336375721,0.0344942734,0.0154453702,-0.0791530013,0.0432731658,0.0650285035,0.0051502362,0.0423676483,-0.007114463,0.0095048156,-0.0538788214,0.1111519784,-0.0180527922,-0.0280200485,-0.0256930478,0.0623122491,0.0211805366,0.1581030786,0.0437217392,-0.0081808651,0.0323508419,-0.020295335,0.0484384485,-0.0059293546,-0.0267229769,0.0214113444,-0.0156375598,-0.0524089821,-0.0430338979,0.0139930248,0.0342623703,-0.0520986505,-0.035864383,-0.0540857688,-0.0456918478,-0.0370431952,-0.0196725149,-0.0244408529,-0.0104857069,0.0666261166,-0.0185784921,-0.0205758512,0.0257778298,0.032287553,0.0457825176,-0.0031068784,-0.0218496472,0.0268104151,-0.0244056582,0.0127987098,0.0337715633,-0.0544908307,-0.0081604589,-0.0010775563,0.0278509539,-0.0332707688,-0.0751567185,0.007563401,-0.0028019557,-0.0031967743]} 11 | 12 | -------------------------------------------------------------------------------- /deploy/docker-compose/data/targets.jsonl: -------------------------------------------------------------------------------- 1 | {"point_uid":"485d0e5b-599f-4844-99ab-d86f376c3214","target":"politics-agent","score":1} 2 | {"point_uid":"442ae99e-c4d4-4316-9067-3b7232f23754","target":"politics-agent","score":1} 3 | {"point_uid":"b9c076c0-e96c-4208-88ec-761b325ca12e","target":"politics-agent","score":1} 4 | {"point_uid":"3d0c0974-0d99-41fd-b7b1-4dfc9155d53f","target":"politics-agent","score":1} 5 | {"point_uid":"887cd819-15f5-4c27-a17b-532fec485271","target":"politics-agent","score":1} 6 | {"point_uid":"b9784f9c-ace9-4939-87d3-83e28dc44b5e","target":"chitchat-agent","score":1} 7 | {"point_uid":"8453a119-eff9-4473-bbb9-359adf9bf4c0","target":"chitchat-agent","score":1} 8 | {"point_uid":"82dafcc6-b4eb-4ea1-967c-5d21453d881c","target":"chitchat-agent","score":1} 9 | {"point_uid":"7f2ad3ce-4505-4d3b-89c1-178abc1aee80","target":"chitchat-agent","score":1} 10 | {"point_uid":"9d7d61c1-a922-456c-913f-3c3a51beb8aa","target":"chitchat-agent","score":1} 11 | 12 | -------------------------------------------------------------------------------- /deploy/docker-compose/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | tei: 3 | # No support for arm64 at this time 4 | platform: linux/amd64 5 | image: ghcr.io/huggingface/text-embeddings-inference:cpu-1.2-grpc 6 | command: 7 | - --model-id=BAAI/bge-small-en-v1.5 8 | - --port=8889 9 | ports: 10 | - "8889" 11 | restart: on-failure 12 | qdrant: 13 | # No support for arm64 at this time 14 | platform: linux/amd64 15 | image: ghcr.io/qdrant/qdrant/qdrant:v1.9.0-unprivileged 16 | command: 17 | - ./qdrant 18 | - --snapshot=/srv/run/embeddings.snapshot:main 19 | ports: 20 | - "6334" 21 | restart: on-failure 22 | volumes: 23 | - ./embeddings.snapshot:/srv/run/embeddings.snapshot 24 | server: 25 | build: 26 | context: ../../ 27 | command: 28 | - server 29 | - --embed-address=tei:8889 30 | - --qdrant-address=qdrant:6334 31 | - --db-path=/srv/run/scores.db 32 | ports: 33 | - "8888:8888" 34 | restart: on-failure 35 | volumes: 36 | - ./scores.db:/srv/run/scores.db 37 | -------------------------------------------------------------------------------- /deploy/pulze-intent-v0.1/.gitignore: -------------------------------------------------------------------------------- 1 | .dist 2 | -------------------------------------------------------------------------------- /deploy/pulze-intent-v0.1/README.md: -------------------------------------------------------------------------------- 1 | # pulze-intent-v0.1 ([model](https://huggingface.co/pulze/intent-v0.1), [dataset](https://huggingface.co/datasets/pulze/intent-v0.1-dataset)) 2 | 3 | Intent-tuned LLM router that selects the best LLM for a user query. 4 | 5 | ## Usage 6 | 7 | ### Local 8 | 9 | Fetch artifacts from Huggingface: 10 | 11 | ```bash 12 | huggingface-cli download pulze/intent-v0.1 --local-dir .dist --local-dir-use-symlinks=False 13 | ``` 14 | 15 | Start the services: 16 | 17 | ```bash 18 | docker compose up -d --build 19 | ``` 20 | 21 | ```bash 22 | curl -s 127.0.0.1:8888/ \ 23 | -X POST \ 24 | -d '{"query":"give me instructions for making ramen at home"}' \ 25 | -H 'Content-Type: application/json' | jq . 26 | ``` 27 | 28 | Output: 29 | 30 | ``` 31 | { 32 | "hits": [ 33 | { 34 | "id": "0c571369-e985-41e1-b14b-3620c4bb40b5", 35 | "category": "writing_cooking_recipe", 36 | "similarity": 0.8069034 37 | }, 38 | { 39 | "id": "9f44d3c0-95f5-43cc-a881-6e23adf9c68b", 40 | "category": "writing_cooking_recipe", 41 | "similarity": 0.778615 42 | }, 43 | { 44 | "id": "21292586-73f3-4bf7-9ada-ae6917d4cd74", 45 | "category": "writing_cooking_recipe", 46 | "similarity": 0.77417636 47 | }, 48 | { 49 | "id": "edd39535-f9b7-4188-a56e-055846d0ba23", 50 | "category": "writing_cooking_recipe", 51 | "similarity": 0.772714 52 | }, 53 | { 54 | "id": "3cc563e1-1816-4ff1-8d2e-60fb9392c6de", 55 | "category": "writing_cooking_recipe", 56 | "similarity": 0.76833653 57 | }, 58 | { 59 | "id": "15c9e10f-d217-418a-b367-a16e3cd3a541", 60 | "category": "writing_cooking_recipe", 61 | "similarity": 0.76015425 62 | }, 63 | { 64 | "id": "ad33a141-269f-4a88-b99c-456cf67d9221", 65 | "category": "writing_cooking_recipe", 66 | "similarity": 0.75983727 67 | }, 68 | { 69 | "id": "d6ee2a78-3b7a-44d6-9778-adc1e1f9a3db", 70 | "category": "writing_cooking_recipe", 71 | "similarity": 0.75918543 72 | }, 73 | { 74 | "id": "afa1f32e-e69e-4d75-9a73-7a11b0259a24", 75 | "category": "writing_cooking_recipe", 76 | "similarity": 0.7565732 77 | }, 78 | { 79 | "id": "5a569973-3934-49f6-8901-11f6b490a6cd", 80 | "category": "writing_cooking_recipe", 81 | "similarity": 0.7564193 82 | } 83 | ], 84 | "scores": [ 85 | { 86 | "target": "gpt-3.5-turbo-0125", 87 | "score": 0.83 88 | }, 89 | { 90 | "target": "command-r-plus", 91 | "score": 0.93 92 | }, 93 | { 94 | "target": "llama-3-70b-instruct", 95 | "score": 0.95 96 | }, 97 | { 98 | "target": "gpt-4-turbo-2024-04-09", 99 | "score": 0.96 100 | }, 101 | { 102 | "target": "dbrx-instruct", 103 | "score": 0.91 104 | }, 105 | { 106 | "target": "mixtral-8x7b-instruct", 107 | "score": 0.91 108 | }, 109 | { 110 | "target": "mistral-small", 111 | "score": 0.9 112 | }, 113 | { 114 | "target": "mistral-large", 115 | "score": 0.91 116 | }, 117 | { 118 | "target": "mistral-medium", 119 | "score": 0.89 120 | }, 121 | { 122 | "target": "claude-3-opus-20240229", 123 | "score": 0.91 124 | }, 125 | { 126 | "target": "claude-3-sonnet-20240229", 127 | "score": 0.9 128 | }, 129 | { 130 | "target": "command-r", 131 | "score": 0.88 132 | }, 133 | { 134 | "target": "claude-3-haiku-20240307", 135 | "score": 0.89 136 | } 137 | ] 138 | } 139 | ``` 140 | 141 | ### Kubernetes 142 | 143 | See this [example](./k8s.yaml). 144 | 145 | ## Models 146 | 147 | - claude-3-haiku-20240307 148 | - claude-3-opus-20240229 149 | - claude-3-sonnet-20240229 150 | - command-r 151 | - command-r-plus 152 | - dbrx-instruct 153 | - gpt-3.5-turbo-0125 154 | - gpt-4-turbo-2024-04-09 155 | - llama-3-70b-instruct 156 | - mistral-large 157 | - mistral-medium 158 | - mistral-small 159 | - mixtral-8x7b-instruct 160 | 161 | ## Data 162 | 163 | ### Prompts and Intent Categories 164 | 165 | Prompt and intent categories are derived from the [GAIR-NLP/Auto-J scenario classification dataset](https://github.com/GAIR-NLP/auto-j/blob/2ae17a3965d933232e9cd50302aa0f176249c83b/README.md?plain=1#L582). 166 | 167 | Citation: 168 | 169 | ``` 170 | @article{li2023generative, 171 | title={Generative Judge for Evaluating Alignment}, 172 | author={Li, Junlong and Sun, Shichao and Yuan, Weizhe and Fan, Run-Ze and Zhao, Hai and Liu, Pengfei}, 173 | journal={arXiv preprint arXiv:2310.05470}, 174 | year={2023} 175 | } 176 | ``` 177 | 178 | ### Response Evaluation 179 | 180 | Candidate model responses were evaluated pairwise using `openai/gpt-4-turbo-2024-04-09`, with the following prompt: 181 | 182 | ``` 183 | You are an expert, impartial judge tasked with evaluating the quality of responses generated by two AI assistants. 184 | 185 | Think step by step, and evaluate the responses, and to the instruction, . Follow these guidelines: 186 | - Avoid any position bias and ensure that the order in which the responses were presented does not influence your judgement 187 | - Do not allow the length of the responses to influence your judgement - a concise response can be as effective as a longer one 188 | - Consider factors such as adherence to the given instruction, helpfulness, relevance, accuracy, depth, creativity, and level of detail 189 | - Be as objective as possible 190 | 191 | Make your decision on which of the two responses is better for the given instruction from the following choices: 192 | If is better, use "1". 193 | If is better, use "2". 194 | If both answers are equally good, use "0". 195 | If both answers are equally bad, use "0". 196 | 197 | 198 | {INSTRUCTION} 199 | 200 | 201 | 202 | {RESPONSE1} 203 | 204 | 205 | 206 | {RESPONSE2} 207 | 208 | ``` 209 | 210 | Each pair of models is subject to 2 matches, with the positions of the respective responses swapped in the evaluation prompt. A model is considered a winner only if 211 | it wins both matches. 212 | 213 | For each prompt, we then compute Bradley-Terry scores for the respective models using the same [method](https://github.com/lm-sys/FastChat/blob/f2e6ca964af7ad0585cadcf16ab98e57297e2133/fastchat/serve/monitor/elo_analysis.py#L57) as that used in the [LMSYS Chatbot Arena Leaderboard](https://chat.lmsys.org/?leaderboard). Finally, we normalize all scores to a scale from 0 to 1 for interoperability with other weighted ranking systems. 214 | 215 | ## Model 216 | 217 | The embedding model was generated by first fine-tuning [`BAAI/bge-base-en-v1.5`](https://huggingface.co/BAAI/bge-base-en-v1.5) with the intent categories from the dataset above, using contrastive learning with cosine similarity loss, and subsequently merging the resultant model with the base model at a 3:2 ratio. 218 | -------------------------------------------------------------------------------- /deploy/pulze-intent-v0.1/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | tei: 3 | # No support for arm64 at this time 4 | platform: linux/amd64 5 | image: ghcr.io/huggingface/text-embeddings-inference:cpu-1.2-grpc 6 | command: 7 | - --model-id=/srv/run/embedding-model 8 | - --port=8889 9 | ports: 10 | - "8889" 11 | restart: on-failure 12 | volumes: 13 | - ./.dist:/srv/run 14 | qdrant: 15 | # No support for arm64 at this time 16 | platform: linux/amd64 17 | image: ghcr.io/qdrant/qdrant/qdrant:v1.9.0-unprivileged 18 | command: 19 | - ./qdrant 20 | - --snapshot=/srv/run/embeddings.snapshot:main 21 | ports: 22 | - "6334" 23 | restart: on-failure 24 | volumes: 25 | - ./.dist:/srv/run 26 | server: 27 | build: 28 | context: ../../ 29 | command: 30 | - server 31 | - --embed-address=tei:8889 32 | - --qdrant-address=qdrant:6334 33 | - --db-path=/srv/run/scores.db 34 | ports: 35 | - "8888:8888" 36 | restart: on-failure 37 | volumes: 38 | - ./.dist:/srv/run 39 | -------------------------------------------------------------------------------- /deploy/pulze-intent-v0.1/k8s.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: llm-router 5 | spec: 6 | selector: 7 | matchLabels: 8 | kubernetes.io/component: llm-router 9 | kubernetes.io/name: llm-router 10 | template: 11 | metadata: 12 | labels: 13 | kubernetes.io/component: llm-router 14 | kubernetes.io/name: llm-router 15 | spec: 16 | affinity: 17 | nodeAffinity: 18 | requiredDuringSchedulingIgnoredDuringExecution: 19 | nodeSelectorTerms: 20 | - matchExpressions: 21 | - key: cloud.google.com/gke-accelerator 22 | operator: In 23 | values: 24 | - nvidia-l4 25 | initContainers: 26 | - name: download-model 27 | image: pkgxdev/pkgx:v1 28 | args: 29 | - pkgx 30 | - huggingface-cli 31 | - download 32 | - --local-dir=/srv/run 33 | - --local-dir-use-symlinks=False 34 | - pulze/intent-v0.1 35 | volumeMounts: 36 | - mountPath: /srv/run 37 | name: run 38 | containers: 39 | - name: main 40 | image: ghcr.io/pulzeai-oss/knn-router:20240503.1_8e42ba6 41 | args: 42 | - server 43 | - --db-path=/srv/run/scores.db 44 | livenessProbe: 45 | failureThreshold: 3 46 | periodSeconds: 10 47 | successThreshold: 1 48 | tcpSocket: 49 | port: http 50 | timeoutSeconds: 1 51 | ports: 52 | - containerPort: 8888 53 | name: http 54 | protocol: TCP 55 | readinessProbe: 56 | failureThreshold: 3 57 | periodSeconds: 10 58 | successThreshold: 1 59 | tcpSocket: 60 | port: http 61 | timeoutSeconds: 1 62 | resources: 63 | limits: 64 | memory: 2Gi 65 | requests: 66 | cpu: "1" 67 | volumeMounts: 68 | - mountPath: /srv/run 69 | name: run 70 | - name: tei 71 | image: ghcr.io/huggingface/text-embeddings-inference:89-1.2-grpc 72 | args: 73 | - --model-id=/srv/run/embedding-model 74 | - --port=8889 75 | livenessProbe: 76 | failureThreshold: 3 77 | periodSeconds: 10 78 | successThreshold: 1 79 | tcpSocket: 80 | port: grpc 81 | timeoutSeconds: 1 82 | ports: 83 | - containerPort: 8889 84 | name: grpc 85 | protocol: TCP 86 | resources: 87 | limits: 88 | memory: 4Gi 89 | nvidia.com/gpu: "1" 90 | requests: 91 | cpu: "1" 92 | volumeMounts: 93 | - mountPath: /dev/shm 94 | name: dshm 95 | - mountPath: /srv/run 96 | name: run 97 | - name: qdrant 98 | image: qdrant/qdrant:v1.9.0 99 | args: 100 | - ./qdrant 101 | - --snapshot=/srv/run/embeddings.snapshot:main 102 | livenessProbe: 103 | failureThreshold: 3 104 | periodSeconds: 10 105 | successThreshold: 1 106 | tcpSocket: 107 | port: grpc 108 | timeoutSeconds: 1 109 | ports: 110 | - containerPort: 6334 111 | name: grpc 112 | protocol: TCP 113 | resources: 114 | limits: 115 | memory: 6Gi 116 | requests: 117 | cpu: "1" 118 | volumeMounts: 119 | - mountPath: /qdrant/storage 120 | name: qdrant 121 | - mountPath: /srv/run 122 | name: run 123 | volumes: 124 | - emptyDir: 125 | medium: Memory 126 | name: dshm 127 | - emptyDir: {} 128 | name: qdrant 129 | - emptyDir: {} 130 | name: run 131 | --- 132 | apiVersion: v1 133 | kind: Service 134 | metadata: 135 | name: llm-router 136 | spec: 137 | ports: 138 | - name: http 139 | port: 8888 140 | protocol: TCP 141 | targetPort: 8888 142 | selector: 143 | kubernetes.io/component: llm-router 144 | kubernetes.io/name: llm-router 145 | type: ClusterIP 146 | -------------------------------------------------------------------------------- /docs/pulze-smart-router.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pulzeai-oss/knn-router/71f796a130e8758cf2313efc6780b78cf2517b6a/docs/pulze-smart-router.png -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/pulzeai-oss/knn-router 2 | 3 | go 1.22.0 4 | 5 | require ( 6 | github.com/pulzeai-oss/knn-router/internal/scorespb v0.0.0-00010101000000-000000000000 7 | github.com/pulzeai-oss/knn-router/internal/teipb v0.0.0-00010101000000-000000000000 8 | github.com/qdrant/go-client v1.7.0 9 | github.com/spf13/cobra v1.8.0 10 | go.etcd.io/bbolt v1.3.9 11 | google.golang.org/grpc v1.61.1 12 | google.golang.org/protobuf v1.32.0 13 | ) 14 | 15 | require ( 16 | github.com/golang/protobuf v1.5.3 // indirect 17 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 18 | github.com/spf13/pflag v1.0.5 // indirect 19 | golang.org/x/net v0.18.0 // indirect 20 | golang.org/x/sys v0.14.0 // indirect 21 | golang.org/x/text v0.14.0 // indirect 22 | google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect 23 | ) 24 | 25 | replace github.com/pulzeai-oss/knn-router/internal/scorespb => ./internal/scorespb 26 | 27 | replace github.com/pulzeai-oss/knn-router/internal/teipb => ./internal/teipb 28 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 5 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 6 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 7 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 8 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 9 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 10 | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 11 | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 12 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 13 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 14 | github.com/qdrant/go-client v1.7.0 h1:2TeeWyZAWIup7vvD7Ne6aAvo0H+F5OUb1pB9Z8Y4pFk= 15 | github.com/qdrant/go-client v1.7.0/go.mod h1:680gkxNAsVtre0Z8hAQmtPzJtz1xFAyCu2TUxULtnoE= 16 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 17 | github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= 18 | github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= 19 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 20 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 21 | github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= 22 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 23 | go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= 24 | go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= 25 | golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= 26 | golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= 27 | golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= 28 | golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 29 | golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= 30 | golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 31 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 32 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 33 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 34 | google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= 35 | google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= 36 | google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= 37 | google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= 38 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 39 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 40 | google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= 41 | google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 42 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 43 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 44 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 45 | -------------------------------------------------------------------------------- /internal/loader/loader.go: -------------------------------------------------------------------------------- 1 | package loader 2 | 3 | import ( 4 | "bufio" 5 | "encoding/json" 6 | "fmt" 7 | "os" 8 | 9 | "github.com/pulzeai-oss/knn-router/internal/scorespb" 10 | "github.com/pulzeai-oss/knn-router/internal/server" 11 | bolt "go.etcd.io/bbolt" 12 | "google.golang.org/protobuf/proto" 13 | ) 14 | 15 | type PointRow struct { 16 | PointUID string `json:"point_uid"` 17 | Category string `json:"category"` 18 | } 19 | 20 | type TargetScoreRow struct { 21 | PointUID string `json:"point_uid"` 22 | Target string `json:"target"` 23 | Score float32 `json:"score"` 24 | } 25 | 26 | type Loader struct { 27 | points map[string]*scorespb.Point 28 | } 29 | 30 | func NewLoader() *Loader { 31 | return &Loader{points: make(map[string]*scorespb.Point)} 32 | } 33 | 34 | func (l *Loader) LoadPoints(pointsDataPath string) error { 35 | // Read in the JSONL-formatted dataset source 36 | dataFile, err := os.Open(pointsDataPath) 37 | if err != nil { 38 | return err 39 | } 40 | defer dataFile.Close() 41 | scanner := bufio.NewScanner(dataFile) 42 | for scanner.Scan() { 43 | line := scanner.Bytes() 44 | if len(line) == 0 { 45 | continue 46 | } 47 | var row PointRow 48 | err := json.Unmarshal(line, &row) 49 | if err != nil { 50 | return err 51 | } 52 | l.points[row.PointUID] = &scorespb.Point{Category: row.Category} 53 | } 54 | if err := scanner.Err(); err != nil { 55 | return err 56 | } 57 | 58 | return nil 59 | } 60 | 61 | func (l *Loader) LoadScores(scoresDataPath string) error { 62 | // Read in the JSONL-formatted dataset source 63 | dataFile, err := os.Open(scoresDataPath) 64 | if err != nil { 65 | return err 66 | } 67 | defer dataFile.Close() 68 | scanner := bufio.NewScanner(dataFile) 69 | for scanner.Scan() { 70 | line := scanner.Bytes() 71 | if len(line) == 0 { 72 | continue 73 | } 74 | var row TargetScoreRow 75 | err := json.Unmarshal(line, &row) 76 | if err != nil { 77 | return err 78 | } 79 | 80 | p, exists := l.points[row.PointUID] 81 | if !exists { 82 | return fmt.Errorf("point UID '%s' not found", row.PointUID) 83 | } 84 | p.Scores = append( 85 | p.Scores, 86 | &scorespb.Score{Target: row.Target, Score: row.Score}, 87 | ) 88 | } 89 | if err := scanner.Err(); err != nil { 90 | return err 91 | } 92 | 93 | return nil 94 | } 95 | 96 | func (l *Loader) SaveScores(scoresDBPath string) error { 97 | // Write to the scores database 98 | scoresDB, err := bolt.Open(scoresDBPath, 0600, nil) 99 | if err != nil { 100 | return err 101 | } 102 | defer scoresDB.Close() 103 | return scoresDB.Update(func(tx *bolt.Tx) error { 104 | for pointUID, point := range l.points { 105 | b, err := tx.CreateBucketIfNotExists([]byte(server.PointsCollection)) 106 | if err != nil { 107 | return err 108 | } 109 | v, err := proto.Marshal(point) 110 | if err != nil { 111 | return err 112 | } 113 | if err := b.Put([]byte(pointUID), v); err != nil { 114 | return err 115 | } 116 | } 117 | 118 | return nil 119 | }) 120 | } 121 | -------------------------------------------------------------------------------- /internal/scorespb/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/pulzeai-oss/knn-router/internal/scorespb 2 | 3 | go 1.22.0 4 | 5 | require google.golang.org/protobuf v1.32.0 6 | -------------------------------------------------------------------------------- /internal/scorespb/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 2 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 3 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 4 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 5 | google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= 6 | google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 7 | -------------------------------------------------------------------------------- /internal/scorespb/scores.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.32.0 4 | // protoc v5.26.1 5 | // source: scores.proto 6 | 7 | package scorespb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type Score struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | Target string `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` 29 | Score float32 `protobuf:"fixed32,2,opt,name=score,proto3" json:"score,omitempty"` 30 | } 31 | 32 | func (x *Score) Reset() { 33 | *x = Score{} 34 | if protoimpl.UnsafeEnabled { 35 | mi := &file_scores_proto_msgTypes[0] 36 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 37 | ms.StoreMessageInfo(mi) 38 | } 39 | } 40 | 41 | func (x *Score) String() string { 42 | return protoimpl.X.MessageStringOf(x) 43 | } 44 | 45 | func (*Score) ProtoMessage() {} 46 | 47 | func (x *Score) ProtoReflect() protoreflect.Message { 48 | mi := &file_scores_proto_msgTypes[0] 49 | if protoimpl.UnsafeEnabled && x != nil { 50 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 51 | if ms.LoadMessageInfo() == nil { 52 | ms.StoreMessageInfo(mi) 53 | } 54 | return ms 55 | } 56 | return mi.MessageOf(x) 57 | } 58 | 59 | // Deprecated: Use Score.ProtoReflect.Descriptor instead. 60 | func (*Score) Descriptor() ([]byte, []int) { 61 | return file_scores_proto_rawDescGZIP(), []int{0} 62 | } 63 | 64 | func (x *Score) GetTarget() string { 65 | if x != nil { 66 | return x.Target 67 | } 68 | return "" 69 | } 70 | 71 | func (x *Score) GetScore() float32 { 72 | if x != nil { 73 | return x.Score 74 | } 75 | return 0 76 | } 77 | 78 | type Point struct { 79 | state protoimpl.MessageState 80 | sizeCache protoimpl.SizeCache 81 | unknownFields protoimpl.UnknownFields 82 | 83 | Category string `protobuf:"bytes,1,opt,name=category,proto3" json:"category,omitempty"` 84 | Scores []*Score `protobuf:"bytes,2,rep,name=scores,proto3" json:"scores,omitempty"` 85 | } 86 | 87 | func (x *Point) Reset() { 88 | *x = Point{} 89 | if protoimpl.UnsafeEnabled { 90 | mi := &file_scores_proto_msgTypes[1] 91 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 92 | ms.StoreMessageInfo(mi) 93 | } 94 | } 95 | 96 | func (x *Point) String() string { 97 | return protoimpl.X.MessageStringOf(x) 98 | } 99 | 100 | func (*Point) ProtoMessage() {} 101 | 102 | func (x *Point) ProtoReflect() protoreflect.Message { 103 | mi := &file_scores_proto_msgTypes[1] 104 | if protoimpl.UnsafeEnabled && x != nil { 105 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 106 | if ms.LoadMessageInfo() == nil { 107 | ms.StoreMessageInfo(mi) 108 | } 109 | return ms 110 | } 111 | return mi.MessageOf(x) 112 | } 113 | 114 | // Deprecated: Use Point.ProtoReflect.Descriptor instead. 115 | func (*Point) Descriptor() ([]byte, []int) { 116 | return file_scores_proto_rawDescGZIP(), []int{1} 117 | } 118 | 119 | func (x *Point) GetCategory() string { 120 | if x != nil { 121 | return x.Category 122 | } 123 | return "" 124 | } 125 | 126 | func (x *Point) GetScores() []*Score { 127 | if x != nil { 128 | return x.Scores 129 | } 130 | return nil 131 | } 132 | 133 | var File_scores_proto protoreflect.FileDescriptor 134 | 135 | var file_scores_proto_rawDesc = []byte{ 136 | 0x0a, 0x0c, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 137 | 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x22, 0x35, 0x0a, 0x05, 0x53, 0x63, 0x6f, 138 | 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 139 | 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 140 | 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 141 | 0x22, 0x4d, 0x0a, 0x05, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 142 | 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 143 | 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x28, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x18, 144 | 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x2e, 0x76, 145 | 0x31, 0x2e, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x42, 146 | 0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x75, 147 | 0x6c, 0x7a, 0x65, 0x61, 0x69, 0x2d, 0x6f, 0x73, 0x73, 0x2f, 0x6b, 0x6e, 0x6e, 0x2d, 0x72, 0x6f, 148 | 0x75, 0x74, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x73, 0x63, 149 | 0x6f, 0x72, 0x65, 0x73, 0x70, 0x62, 0x3b, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x70, 0x62, 0x62, 150 | 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 151 | } 152 | 153 | var ( 154 | file_scores_proto_rawDescOnce sync.Once 155 | file_scores_proto_rawDescData = file_scores_proto_rawDesc 156 | ) 157 | 158 | func file_scores_proto_rawDescGZIP() []byte { 159 | file_scores_proto_rawDescOnce.Do(func() { 160 | file_scores_proto_rawDescData = protoimpl.X.CompressGZIP(file_scores_proto_rawDescData) 161 | }) 162 | return file_scores_proto_rawDescData 163 | } 164 | 165 | var file_scores_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 166 | var file_scores_proto_goTypes = []interface{}{ 167 | (*Score)(nil), // 0: scores.v1.Score 168 | (*Point)(nil), // 1: scores.v1.Point 169 | } 170 | var file_scores_proto_depIdxs = []int32{ 171 | 0, // 0: scores.v1.Point.scores:type_name -> scores.v1.Score 172 | 1, // [1:1] is the sub-list for method output_type 173 | 1, // [1:1] is the sub-list for method input_type 174 | 1, // [1:1] is the sub-list for extension type_name 175 | 1, // [1:1] is the sub-list for extension extendee 176 | 0, // [0:1] is the sub-list for field type_name 177 | } 178 | 179 | func init() { file_scores_proto_init() } 180 | func file_scores_proto_init() { 181 | if File_scores_proto != nil { 182 | return 183 | } 184 | if !protoimpl.UnsafeEnabled { 185 | file_scores_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 186 | switch v := v.(*Score); i { 187 | case 0: 188 | return &v.state 189 | case 1: 190 | return &v.sizeCache 191 | case 2: 192 | return &v.unknownFields 193 | default: 194 | return nil 195 | } 196 | } 197 | file_scores_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 198 | switch v := v.(*Point); i { 199 | case 0: 200 | return &v.state 201 | case 1: 202 | return &v.sizeCache 203 | case 2: 204 | return &v.unknownFields 205 | default: 206 | return nil 207 | } 208 | } 209 | } 210 | type x struct{} 211 | out := protoimpl.TypeBuilder{ 212 | File: protoimpl.DescBuilder{ 213 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 214 | RawDescriptor: file_scores_proto_rawDesc, 215 | NumEnums: 0, 216 | NumMessages: 2, 217 | NumExtensions: 0, 218 | NumServices: 0, 219 | }, 220 | GoTypes: file_scores_proto_goTypes, 221 | DependencyIndexes: file_scores_proto_depIdxs, 222 | MessageInfos: file_scores_proto_msgTypes, 223 | }.Build() 224 | File_scores_proto = out.File 225 | file_scores_proto_rawDesc = nil 226 | file_scores_proto_goTypes = nil 227 | file_scores_proto_depIdxs = nil 228 | } 229 | -------------------------------------------------------------------------------- /internal/server/server.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "math" 9 | "net/http" 10 | 11 | "github.com/pulzeai-oss/knn-router/internal/scorespb" 12 | "github.com/pulzeai-oss/knn-router/internal/teipb" 13 | qdrant "github.com/qdrant/go-client/qdrant" 14 | bolt "go.etcd.io/bbolt" 15 | "google.golang.org/grpc" 16 | "google.golang.org/protobuf/proto" 17 | ) 18 | 19 | const ( 20 | PointsCollection = "main" 21 | ) 22 | 23 | type TruncateStrategy uint8 24 | 25 | const ( 26 | Head TruncateStrategy = iota + 1 27 | Tail 28 | Middle 29 | Ends 30 | ) 31 | 32 | type Request struct { 33 | Query string `json:"query"` 34 | TruncateStrategy TruncateStrategy `json:"truncate_strategy"` 35 | } 36 | 37 | type Score struct { 38 | Target string `json:"target"` 39 | Score float32 `json:"score"` 40 | } 41 | 42 | type Hit struct { 43 | ID string `json:"id"` 44 | Category string `json:"category"` 45 | Similarity float32 `json:"similarity"` 46 | } 47 | 48 | type Response struct { 49 | Hits []Hit `json:"hits"` 50 | Scores []Score `json:"scores"` 51 | } 52 | 53 | type Server struct { 54 | embedClient teipb.EmbedClient 55 | tokenizeClient teipb.TokenizeClient 56 | pointsClient qdrant.PointsClient 57 | DB *bolt.DB 58 | topK int 59 | maxSequenceLength int 60 | } 61 | 62 | func NewServer( 63 | embedConn *grpc.ClientConn, 64 | qdrantConn *grpc.ClientConn, 65 | DB *bolt.DB, 66 | topK int, 67 | maxSequenceLength int, 68 | ) *Server { 69 | return &Server{ 70 | embedClient: teipb.NewEmbedClient(embedConn), 71 | tokenizeClient: teipb.NewTokenizeClient(embedConn), 72 | pointsClient: qdrant.NewPointsClient(qdrantConn), 73 | DB: DB, 74 | topK: topK, 75 | maxSequenceLength: maxSequenceLength, 76 | } 77 | } 78 | 79 | func (s *Server) handler(w http.ResponseWriter, r *http.Request) { 80 | // TODO (jeev): Switch to GRPC server 81 | body, err := io.ReadAll(r.Body) 82 | if err != nil { 83 | http.Error(w, "failed to read request body", http.StatusBadRequest) 84 | return 85 | } 86 | defer r.Body.Close() 87 | 88 | // Parse the payload from the request body 89 | payload := Request{TruncateStrategy: Middle} 90 | err = json.Unmarshal(body, &payload) 91 | if err != nil { 92 | http.Error(w, "failed to parse request body", http.StatusBadRequest) 93 | return 94 | } 95 | if payload.Query == "" { 96 | http.Error(w, "query is required", http.StatusBadRequest) 97 | return 98 | } 99 | 100 | res, err := s.query(r.Context(), &payload) 101 | if err != nil { 102 | http.Error(w, "failed to retrieve scores", http.StatusInternalServerError) 103 | return 104 | } 105 | 106 | w.Header().Set("Content-Type", "application/json") 107 | if err := json.NewEncoder(w).Encode(res); err != nil { 108 | http.Error(w, "failed to encode response", http.StatusInternalServerError) 109 | } 110 | } 111 | 112 | func (s *Server) sanitizeQuery( 113 | ctx context.Context, 114 | req *Request, 115 | ) (string, error) { 116 | encodeResp, err := s.tokenizeClient.Tokenize(ctx, &teipb.EncodeRequest{Inputs: req.Query}) 117 | if err != nil { 118 | return "", fmt.Errorf("failed to tokenize query: %v", err) 119 | } 120 | numTokens := len(encodeResp.GetTokens()) 121 | if numTokens <= s.maxSequenceLength { 122 | return req.Query, nil 123 | } 124 | 125 | switch req.TruncateStrategy { 126 | case Head: 127 | startToken := encodeResp.GetTokens()[numTokens-s.maxSequenceLength] 128 | return req.Query[*startToken.Start:], nil 129 | case Tail: 130 | endToken := encodeResp.GetTokens()[s.maxSequenceLength-1] 131 | return req.Query[:*endToken.Stop], nil 132 | case Middle: 133 | offset := s.maxSequenceLength / 2 134 | startTruncateToken := encodeResp.GetTokens()[offset] 135 | endTruncateToken := encodeResp.GetTokens()[numTokens+offset-s.maxSequenceLength-1] 136 | return req.Query[:*startTruncateToken.Start] + req.Query[*endTruncateToken.Stop:], nil 137 | case Ends: 138 | offset := (numTokens - s.maxSequenceLength) / 2 139 | startToken := encodeResp.GetTokens()[offset] 140 | endToken := encodeResp.GetTokens()[offset+s.maxSequenceLength-1] 141 | return req.Query[*startToken.Start:*endToken.Stop], nil 142 | } 143 | 144 | return "", fmt.Errorf("unsupported truncate strategy: %v", req.TruncateStrategy) 145 | } 146 | 147 | func (s *Server) query( 148 | ctx context.Context, 149 | req *Request, 150 | ) (*Response, error) { 151 | query, err := s.sanitizeQuery(ctx, req) 152 | if err != nil { 153 | return nil, fmt.Errorf("failed to sanitize query: %v", err) 154 | } 155 | embedResp, err := s.embedClient.Embed(ctx, &teipb.EmbedRequest{Inputs: query, Truncate: true}) 156 | if err != nil { 157 | return nil, fmt.Errorf("failed to compute embedding: %v", err) 158 | } 159 | 160 | search, err := s.pointsClient.Search(ctx, &qdrant.SearchPoints{ 161 | CollectionName: PointsCollection, 162 | Vector: embedResp.GetEmbeddings(), 163 | Limit: uint64(s.topK), 164 | WithVectors: &qdrant.WithVectorsSelector{ 165 | SelectorOptions: &qdrant.WithVectorsSelector_Enable{Enable: false}, 166 | }, 167 | WithPayload: &qdrant.WithPayloadSelector{ 168 | SelectorOptions: &qdrant.WithPayloadSelector_Enable{Enable: false}, 169 | }, 170 | }) 171 | if err != nil { 172 | return nil, fmt.Errorf("failed to search for nearest neighbors: %v", err) 173 | } 174 | 175 | // Initialize response 176 | var res Response 177 | 178 | // Aggregate scores from nearest neighbors 179 | var weightSum float32 180 | scoresSum := make(map[string]float32) 181 | for _, pt := range search.GetResult() { 182 | uid := pt.GetId().GetUuid() 183 | weight := pt.GetScore() 184 | weightSum += weight 185 | // Lookup target scores in DB for given UID 186 | err = s.DB.View(func(tx *bolt.Tx) error { 187 | b := tx.Bucket([]byte(PointsCollection)) 188 | v := b.Get([]byte(uid)) 189 | if v == nil { 190 | return fmt.Errorf("could not find targets for nearest neighbor UID %s", uid) 191 | } 192 | var payload scorespb.Point 193 | err = proto.Unmarshal(v, &payload) 194 | if err != nil { 195 | return err 196 | } 197 | res.Hits = append( 198 | res.Hits, 199 | Hit{ 200 | ID: uid, 201 | Category: payload.GetCategory(), 202 | Similarity: weight, 203 | }, 204 | ) 205 | for _, score := range payload.GetScores() { 206 | scoresSum[score.GetTarget()] += score.GetScore() * weight 207 | } 208 | return nil 209 | }) 210 | if err != nil { 211 | return nil, fmt.Errorf( 212 | "failed to retrieve targets for nearest neighbor UID %s: %v", 213 | uid, 214 | err, 215 | ) 216 | } 217 | } 218 | // Normalize the accumulated scores by dividing by the sum of weighted distances 219 | for target, score := range scoresSum { 220 | normalizedScore := float32(math.Round(float64(score/weightSum)*100)) / 100 221 | res.Scores = append( 222 | res.Scores, 223 | Score{Target: target, Score: normalizedScore}, 224 | ) 225 | } 226 | return &res, nil 227 | } 228 | 229 | func (s *Server) ListenAndServe(bindAddr string) error { 230 | // TODO (jeev): Add prometheus metrics 231 | http.HandleFunc("/", s.handler) 232 | return http.ListenAndServe(bindAddr, nil) 233 | } 234 | -------------------------------------------------------------------------------- /internal/teipb/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/pulzeai-oss/knn-router/internal/teipb 2 | 3 | go 1.22.0 4 | 5 | require ( 6 | google.golang.org/grpc v1.61.1 7 | google.golang.org/protobuf v1.32.0 8 | ) 9 | 10 | require ( 11 | github.com/golang/protobuf v1.5.3 // indirect 12 | golang.org/x/net v0.18.0 // indirect 13 | golang.org/x/sys v0.14.0 // indirect 14 | golang.org/x/text v0.14.0 // indirect 15 | google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /internal/teipb/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 2 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 3 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 4 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 5 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 6 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 7 | golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= 8 | golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= 9 | golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= 10 | golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 11 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 12 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 13 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 14 | google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= 15 | google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= 16 | google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= 17 | google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= 18 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 19 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 20 | google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= 21 | google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 22 | -------------------------------------------------------------------------------- /internal/teipb/tei.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.32.0 4 | // protoc v5.26.1 5 | // source: tei.proto 6 | 7 | package teipb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type ModelType int32 24 | 25 | const ( 26 | ModelType_MODEL_TYPE_EMBEDDING ModelType = 0 27 | ModelType_MODEL_TYPE_CLASSIFIER ModelType = 1 28 | ModelType_MODEL_TYPE_RERANKER ModelType = 2 29 | ) 30 | 31 | // Enum value maps for ModelType. 32 | var ( 33 | ModelType_name = map[int32]string{ 34 | 0: "MODEL_TYPE_EMBEDDING", 35 | 1: "MODEL_TYPE_CLASSIFIER", 36 | 2: "MODEL_TYPE_RERANKER", 37 | } 38 | ModelType_value = map[string]int32{ 39 | "MODEL_TYPE_EMBEDDING": 0, 40 | "MODEL_TYPE_CLASSIFIER": 1, 41 | "MODEL_TYPE_RERANKER": 2, 42 | } 43 | ) 44 | 45 | func (x ModelType) Enum() *ModelType { 46 | p := new(ModelType) 47 | *p = x 48 | return p 49 | } 50 | 51 | func (x ModelType) String() string { 52 | return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) 53 | } 54 | 55 | func (ModelType) Descriptor() protoreflect.EnumDescriptor { 56 | return file_tei_proto_enumTypes[0].Descriptor() 57 | } 58 | 59 | func (ModelType) Type() protoreflect.EnumType { 60 | return &file_tei_proto_enumTypes[0] 61 | } 62 | 63 | func (x ModelType) Number() protoreflect.EnumNumber { 64 | return protoreflect.EnumNumber(x) 65 | } 66 | 67 | // Deprecated: Use ModelType.Descriptor instead. 68 | func (ModelType) EnumDescriptor() ([]byte, []int) { 69 | return file_tei_proto_rawDescGZIP(), []int{0} 70 | } 71 | 72 | type InfoRequest struct { 73 | state protoimpl.MessageState 74 | sizeCache protoimpl.SizeCache 75 | unknownFields protoimpl.UnknownFields 76 | } 77 | 78 | func (x *InfoRequest) Reset() { 79 | *x = InfoRequest{} 80 | if protoimpl.UnsafeEnabled { 81 | mi := &file_tei_proto_msgTypes[0] 82 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 83 | ms.StoreMessageInfo(mi) 84 | } 85 | } 86 | 87 | func (x *InfoRequest) String() string { 88 | return protoimpl.X.MessageStringOf(x) 89 | } 90 | 91 | func (*InfoRequest) ProtoMessage() {} 92 | 93 | func (x *InfoRequest) ProtoReflect() protoreflect.Message { 94 | mi := &file_tei_proto_msgTypes[0] 95 | if protoimpl.UnsafeEnabled && x != nil { 96 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 97 | if ms.LoadMessageInfo() == nil { 98 | ms.StoreMessageInfo(mi) 99 | } 100 | return ms 101 | } 102 | return mi.MessageOf(x) 103 | } 104 | 105 | // Deprecated: Use InfoRequest.ProtoReflect.Descriptor instead. 106 | func (*InfoRequest) Descriptor() ([]byte, []int) { 107 | return file_tei_proto_rawDescGZIP(), []int{0} 108 | } 109 | 110 | type InfoResponse struct { 111 | state protoimpl.MessageState 112 | sizeCache protoimpl.SizeCache 113 | unknownFields protoimpl.UnknownFields 114 | 115 | Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` 116 | Sha *string `protobuf:"bytes,2,opt,name=sha,proto3,oneof" json:"sha,omitempty"` 117 | DockerLabel *string `protobuf:"bytes,3,opt,name=docker_label,json=dockerLabel,proto3,oneof" json:"docker_label,omitempty"` 118 | ModelId string `protobuf:"bytes,4,opt,name=model_id,json=modelId,proto3" json:"model_id,omitempty"` 119 | ModelSha *string `protobuf:"bytes,5,opt,name=model_sha,json=modelSha,proto3,oneof" json:"model_sha,omitempty"` 120 | ModelDtype string `protobuf:"bytes,6,opt,name=model_dtype,json=modelDtype,proto3" json:"model_dtype,omitempty"` 121 | ModelType ModelType `protobuf:"varint,7,opt,name=model_type,json=modelType,proto3,enum=tei.v1.ModelType" json:"model_type,omitempty"` 122 | MaxConcurrentRequests uint32 `protobuf:"varint,8,opt,name=max_concurrent_requests,json=maxConcurrentRequests,proto3" json:"max_concurrent_requests,omitempty"` 123 | MaxInputLength uint32 `protobuf:"varint,9,opt,name=max_input_length,json=maxInputLength,proto3" json:"max_input_length,omitempty"` 124 | MaxBatchTokens uint32 `protobuf:"varint,10,opt,name=max_batch_tokens,json=maxBatchTokens,proto3" json:"max_batch_tokens,omitempty"` 125 | MaxBatchRequests *uint32 `protobuf:"varint,11,opt,name=max_batch_requests,json=maxBatchRequests,proto3,oneof" json:"max_batch_requests,omitempty"` 126 | MaxClientBatchSize uint32 `protobuf:"varint,12,opt,name=max_client_batch_size,json=maxClientBatchSize,proto3" json:"max_client_batch_size,omitempty"` 127 | TokenizationWorkers uint32 `protobuf:"varint,13,opt,name=tokenization_workers,json=tokenizationWorkers,proto3" json:"tokenization_workers,omitempty"` 128 | } 129 | 130 | func (x *InfoResponse) Reset() { 131 | *x = InfoResponse{} 132 | if protoimpl.UnsafeEnabled { 133 | mi := &file_tei_proto_msgTypes[1] 134 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 135 | ms.StoreMessageInfo(mi) 136 | } 137 | } 138 | 139 | func (x *InfoResponse) String() string { 140 | return protoimpl.X.MessageStringOf(x) 141 | } 142 | 143 | func (*InfoResponse) ProtoMessage() {} 144 | 145 | func (x *InfoResponse) ProtoReflect() protoreflect.Message { 146 | mi := &file_tei_proto_msgTypes[1] 147 | if protoimpl.UnsafeEnabled && x != nil { 148 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 149 | if ms.LoadMessageInfo() == nil { 150 | ms.StoreMessageInfo(mi) 151 | } 152 | return ms 153 | } 154 | return mi.MessageOf(x) 155 | } 156 | 157 | // Deprecated: Use InfoResponse.ProtoReflect.Descriptor instead. 158 | func (*InfoResponse) Descriptor() ([]byte, []int) { 159 | return file_tei_proto_rawDescGZIP(), []int{1} 160 | } 161 | 162 | func (x *InfoResponse) GetVersion() string { 163 | if x != nil { 164 | return x.Version 165 | } 166 | return "" 167 | } 168 | 169 | func (x *InfoResponse) GetSha() string { 170 | if x != nil && x.Sha != nil { 171 | return *x.Sha 172 | } 173 | return "" 174 | } 175 | 176 | func (x *InfoResponse) GetDockerLabel() string { 177 | if x != nil && x.DockerLabel != nil { 178 | return *x.DockerLabel 179 | } 180 | return "" 181 | } 182 | 183 | func (x *InfoResponse) GetModelId() string { 184 | if x != nil { 185 | return x.ModelId 186 | } 187 | return "" 188 | } 189 | 190 | func (x *InfoResponse) GetModelSha() string { 191 | if x != nil && x.ModelSha != nil { 192 | return *x.ModelSha 193 | } 194 | return "" 195 | } 196 | 197 | func (x *InfoResponse) GetModelDtype() string { 198 | if x != nil { 199 | return x.ModelDtype 200 | } 201 | return "" 202 | } 203 | 204 | func (x *InfoResponse) GetModelType() ModelType { 205 | if x != nil { 206 | return x.ModelType 207 | } 208 | return ModelType_MODEL_TYPE_EMBEDDING 209 | } 210 | 211 | func (x *InfoResponse) GetMaxConcurrentRequests() uint32 { 212 | if x != nil { 213 | return x.MaxConcurrentRequests 214 | } 215 | return 0 216 | } 217 | 218 | func (x *InfoResponse) GetMaxInputLength() uint32 { 219 | if x != nil { 220 | return x.MaxInputLength 221 | } 222 | return 0 223 | } 224 | 225 | func (x *InfoResponse) GetMaxBatchTokens() uint32 { 226 | if x != nil { 227 | return x.MaxBatchTokens 228 | } 229 | return 0 230 | } 231 | 232 | func (x *InfoResponse) GetMaxBatchRequests() uint32 { 233 | if x != nil && x.MaxBatchRequests != nil { 234 | return *x.MaxBatchRequests 235 | } 236 | return 0 237 | } 238 | 239 | func (x *InfoResponse) GetMaxClientBatchSize() uint32 { 240 | if x != nil { 241 | return x.MaxClientBatchSize 242 | } 243 | return 0 244 | } 245 | 246 | func (x *InfoResponse) GetTokenizationWorkers() uint32 { 247 | if x != nil { 248 | return x.TokenizationWorkers 249 | } 250 | return 0 251 | } 252 | 253 | type Metadata struct { 254 | state protoimpl.MessageState 255 | sizeCache protoimpl.SizeCache 256 | unknownFields protoimpl.UnknownFields 257 | 258 | ComputeChars uint32 `protobuf:"varint,1,opt,name=compute_chars,json=computeChars,proto3" json:"compute_chars,omitempty"` 259 | ComputeTokens uint32 `protobuf:"varint,2,opt,name=compute_tokens,json=computeTokens,proto3" json:"compute_tokens,omitempty"` 260 | TotalTimeNs uint64 `protobuf:"varint,3,opt,name=total_time_ns,json=totalTimeNs,proto3" json:"total_time_ns,omitempty"` 261 | TokenizationTimeNs uint64 `protobuf:"varint,4,opt,name=tokenization_time_ns,json=tokenizationTimeNs,proto3" json:"tokenization_time_ns,omitempty"` 262 | QueueTimeNs uint64 `protobuf:"varint,5,opt,name=queue_time_ns,json=queueTimeNs,proto3" json:"queue_time_ns,omitempty"` 263 | InferenceTimeNs uint64 `protobuf:"varint,6,opt,name=inference_time_ns,json=inferenceTimeNs,proto3" json:"inference_time_ns,omitempty"` 264 | } 265 | 266 | func (x *Metadata) Reset() { 267 | *x = Metadata{} 268 | if protoimpl.UnsafeEnabled { 269 | mi := &file_tei_proto_msgTypes[2] 270 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 271 | ms.StoreMessageInfo(mi) 272 | } 273 | } 274 | 275 | func (x *Metadata) String() string { 276 | return protoimpl.X.MessageStringOf(x) 277 | } 278 | 279 | func (*Metadata) ProtoMessage() {} 280 | 281 | func (x *Metadata) ProtoReflect() protoreflect.Message { 282 | mi := &file_tei_proto_msgTypes[2] 283 | if protoimpl.UnsafeEnabled && x != nil { 284 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 285 | if ms.LoadMessageInfo() == nil { 286 | ms.StoreMessageInfo(mi) 287 | } 288 | return ms 289 | } 290 | return mi.MessageOf(x) 291 | } 292 | 293 | // Deprecated: Use Metadata.ProtoReflect.Descriptor instead. 294 | func (*Metadata) Descriptor() ([]byte, []int) { 295 | return file_tei_proto_rawDescGZIP(), []int{2} 296 | } 297 | 298 | func (x *Metadata) GetComputeChars() uint32 { 299 | if x != nil { 300 | return x.ComputeChars 301 | } 302 | return 0 303 | } 304 | 305 | func (x *Metadata) GetComputeTokens() uint32 { 306 | if x != nil { 307 | return x.ComputeTokens 308 | } 309 | return 0 310 | } 311 | 312 | func (x *Metadata) GetTotalTimeNs() uint64 { 313 | if x != nil { 314 | return x.TotalTimeNs 315 | } 316 | return 0 317 | } 318 | 319 | func (x *Metadata) GetTokenizationTimeNs() uint64 { 320 | if x != nil { 321 | return x.TokenizationTimeNs 322 | } 323 | return 0 324 | } 325 | 326 | func (x *Metadata) GetQueueTimeNs() uint64 { 327 | if x != nil { 328 | return x.QueueTimeNs 329 | } 330 | return 0 331 | } 332 | 333 | func (x *Metadata) GetInferenceTimeNs() uint64 { 334 | if x != nil { 335 | return x.InferenceTimeNs 336 | } 337 | return 0 338 | } 339 | 340 | type EmbedRequest struct { 341 | state protoimpl.MessageState 342 | sizeCache protoimpl.SizeCache 343 | unknownFields protoimpl.UnknownFields 344 | 345 | Inputs string `protobuf:"bytes,1,opt,name=inputs,proto3" json:"inputs,omitempty"` 346 | Truncate bool `protobuf:"varint,2,opt,name=truncate,proto3" json:"truncate,omitempty"` 347 | Normalize bool `protobuf:"varint,3,opt,name=normalize,proto3" json:"normalize,omitempty"` 348 | } 349 | 350 | func (x *EmbedRequest) Reset() { 351 | *x = EmbedRequest{} 352 | if protoimpl.UnsafeEnabled { 353 | mi := &file_tei_proto_msgTypes[3] 354 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 355 | ms.StoreMessageInfo(mi) 356 | } 357 | } 358 | 359 | func (x *EmbedRequest) String() string { 360 | return protoimpl.X.MessageStringOf(x) 361 | } 362 | 363 | func (*EmbedRequest) ProtoMessage() {} 364 | 365 | func (x *EmbedRequest) ProtoReflect() protoreflect.Message { 366 | mi := &file_tei_proto_msgTypes[3] 367 | if protoimpl.UnsafeEnabled && x != nil { 368 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 369 | if ms.LoadMessageInfo() == nil { 370 | ms.StoreMessageInfo(mi) 371 | } 372 | return ms 373 | } 374 | return mi.MessageOf(x) 375 | } 376 | 377 | // Deprecated: Use EmbedRequest.ProtoReflect.Descriptor instead. 378 | func (*EmbedRequest) Descriptor() ([]byte, []int) { 379 | return file_tei_proto_rawDescGZIP(), []int{3} 380 | } 381 | 382 | func (x *EmbedRequest) GetInputs() string { 383 | if x != nil { 384 | return x.Inputs 385 | } 386 | return "" 387 | } 388 | 389 | func (x *EmbedRequest) GetTruncate() bool { 390 | if x != nil { 391 | return x.Truncate 392 | } 393 | return false 394 | } 395 | 396 | func (x *EmbedRequest) GetNormalize() bool { 397 | if x != nil { 398 | return x.Normalize 399 | } 400 | return false 401 | } 402 | 403 | type EmbedResponse struct { 404 | state protoimpl.MessageState 405 | sizeCache protoimpl.SizeCache 406 | unknownFields protoimpl.UnknownFields 407 | 408 | Embeddings []float32 `protobuf:"fixed32,1,rep,packed,name=embeddings,proto3" json:"embeddings,omitempty"` 409 | Metadata *Metadata `protobuf:"bytes,2,opt,name=metadata,proto3" json:"metadata,omitempty"` 410 | } 411 | 412 | func (x *EmbedResponse) Reset() { 413 | *x = EmbedResponse{} 414 | if protoimpl.UnsafeEnabled { 415 | mi := &file_tei_proto_msgTypes[4] 416 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 417 | ms.StoreMessageInfo(mi) 418 | } 419 | } 420 | 421 | func (x *EmbedResponse) String() string { 422 | return protoimpl.X.MessageStringOf(x) 423 | } 424 | 425 | func (*EmbedResponse) ProtoMessage() {} 426 | 427 | func (x *EmbedResponse) ProtoReflect() protoreflect.Message { 428 | mi := &file_tei_proto_msgTypes[4] 429 | if protoimpl.UnsafeEnabled && x != nil { 430 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 431 | if ms.LoadMessageInfo() == nil { 432 | ms.StoreMessageInfo(mi) 433 | } 434 | return ms 435 | } 436 | return mi.MessageOf(x) 437 | } 438 | 439 | // Deprecated: Use EmbedResponse.ProtoReflect.Descriptor instead. 440 | func (*EmbedResponse) Descriptor() ([]byte, []int) { 441 | return file_tei_proto_rawDescGZIP(), []int{4} 442 | } 443 | 444 | func (x *EmbedResponse) GetEmbeddings() []float32 { 445 | if x != nil { 446 | return x.Embeddings 447 | } 448 | return nil 449 | } 450 | 451 | func (x *EmbedResponse) GetMetadata() *Metadata { 452 | if x != nil { 453 | return x.Metadata 454 | } 455 | return nil 456 | } 457 | 458 | type EncodeRequest struct { 459 | state protoimpl.MessageState 460 | sizeCache protoimpl.SizeCache 461 | unknownFields protoimpl.UnknownFields 462 | 463 | Inputs string `protobuf:"bytes,1,opt,name=inputs,proto3" json:"inputs,omitempty"` 464 | AddSpecialTokens bool `protobuf:"varint,2,opt,name=add_special_tokens,json=addSpecialTokens,proto3" json:"add_special_tokens,omitempty"` 465 | } 466 | 467 | func (x *EncodeRequest) Reset() { 468 | *x = EncodeRequest{} 469 | if protoimpl.UnsafeEnabled { 470 | mi := &file_tei_proto_msgTypes[5] 471 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 472 | ms.StoreMessageInfo(mi) 473 | } 474 | } 475 | 476 | func (x *EncodeRequest) String() string { 477 | return protoimpl.X.MessageStringOf(x) 478 | } 479 | 480 | func (*EncodeRequest) ProtoMessage() {} 481 | 482 | func (x *EncodeRequest) ProtoReflect() protoreflect.Message { 483 | mi := &file_tei_proto_msgTypes[5] 484 | if protoimpl.UnsafeEnabled && x != nil { 485 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 486 | if ms.LoadMessageInfo() == nil { 487 | ms.StoreMessageInfo(mi) 488 | } 489 | return ms 490 | } 491 | return mi.MessageOf(x) 492 | } 493 | 494 | // Deprecated: Use EncodeRequest.ProtoReflect.Descriptor instead. 495 | func (*EncodeRequest) Descriptor() ([]byte, []int) { 496 | return file_tei_proto_rawDescGZIP(), []int{5} 497 | } 498 | 499 | func (x *EncodeRequest) GetInputs() string { 500 | if x != nil { 501 | return x.Inputs 502 | } 503 | return "" 504 | } 505 | 506 | func (x *EncodeRequest) GetAddSpecialTokens() bool { 507 | if x != nil { 508 | return x.AddSpecialTokens 509 | } 510 | return false 511 | } 512 | 513 | type SimpleToken struct { 514 | state protoimpl.MessageState 515 | sizeCache protoimpl.SizeCache 516 | unknownFields protoimpl.UnknownFields 517 | 518 | Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` 519 | Text string `protobuf:"bytes,2,opt,name=text,proto3" json:"text,omitempty"` 520 | Special bool `protobuf:"varint,3,opt,name=special,proto3" json:"special,omitempty"` 521 | Start *uint32 `protobuf:"varint,4,opt,name=start,proto3,oneof" json:"start,omitempty"` 522 | Stop *uint32 `protobuf:"varint,5,opt,name=stop,proto3,oneof" json:"stop,omitempty"` 523 | } 524 | 525 | func (x *SimpleToken) Reset() { 526 | *x = SimpleToken{} 527 | if protoimpl.UnsafeEnabled { 528 | mi := &file_tei_proto_msgTypes[6] 529 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 530 | ms.StoreMessageInfo(mi) 531 | } 532 | } 533 | 534 | func (x *SimpleToken) String() string { 535 | return protoimpl.X.MessageStringOf(x) 536 | } 537 | 538 | func (*SimpleToken) ProtoMessage() {} 539 | 540 | func (x *SimpleToken) ProtoReflect() protoreflect.Message { 541 | mi := &file_tei_proto_msgTypes[6] 542 | if protoimpl.UnsafeEnabled && x != nil { 543 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 544 | if ms.LoadMessageInfo() == nil { 545 | ms.StoreMessageInfo(mi) 546 | } 547 | return ms 548 | } 549 | return mi.MessageOf(x) 550 | } 551 | 552 | // Deprecated: Use SimpleToken.ProtoReflect.Descriptor instead. 553 | func (*SimpleToken) Descriptor() ([]byte, []int) { 554 | return file_tei_proto_rawDescGZIP(), []int{6} 555 | } 556 | 557 | func (x *SimpleToken) GetId() uint32 { 558 | if x != nil { 559 | return x.Id 560 | } 561 | return 0 562 | } 563 | 564 | func (x *SimpleToken) GetText() string { 565 | if x != nil { 566 | return x.Text 567 | } 568 | return "" 569 | } 570 | 571 | func (x *SimpleToken) GetSpecial() bool { 572 | if x != nil { 573 | return x.Special 574 | } 575 | return false 576 | } 577 | 578 | func (x *SimpleToken) GetStart() uint32 { 579 | if x != nil && x.Start != nil { 580 | return *x.Start 581 | } 582 | return 0 583 | } 584 | 585 | func (x *SimpleToken) GetStop() uint32 { 586 | if x != nil && x.Stop != nil { 587 | return *x.Stop 588 | } 589 | return 0 590 | } 591 | 592 | type EncodeResponse struct { 593 | state protoimpl.MessageState 594 | sizeCache protoimpl.SizeCache 595 | unknownFields protoimpl.UnknownFields 596 | 597 | Tokens []*SimpleToken `protobuf:"bytes,1,rep,name=tokens,proto3" json:"tokens,omitempty"` 598 | } 599 | 600 | func (x *EncodeResponse) Reset() { 601 | *x = EncodeResponse{} 602 | if protoimpl.UnsafeEnabled { 603 | mi := &file_tei_proto_msgTypes[7] 604 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 605 | ms.StoreMessageInfo(mi) 606 | } 607 | } 608 | 609 | func (x *EncodeResponse) String() string { 610 | return protoimpl.X.MessageStringOf(x) 611 | } 612 | 613 | func (*EncodeResponse) ProtoMessage() {} 614 | 615 | func (x *EncodeResponse) ProtoReflect() protoreflect.Message { 616 | mi := &file_tei_proto_msgTypes[7] 617 | if protoimpl.UnsafeEnabled && x != nil { 618 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 619 | if ms.LoadMessageInfo() == nil { 620 | ms.StoreMessageInfo(mi) 621 | } 622 | return ms 623 | } 624 | return mi.MessageOf(x) 625 | } 626 | 627 | // Deprecated: Use EncodeResponse.ProtoReflect.Descriptor instead. 628 | func (*EncodeResponse) Descriptor() ([]byte, []int) { 629 | return file_tei_proto_rawDescGZIP(), []int{7} 630 | } 631 | 632 | func (x *EncodeResponse) GetTokens() []*SimpleToken { 633 | if x != nil { 634 | return x.Tokens 635 | } 636 | return nil 637 | } 638 | 639 | var File_tei_proto protoreflect.FileDescriptor 640 | 641 | var file_tei_proto_rawDesc = []byte{ 642 | 0x0a, 0x09, 0x74, 0x65, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x74, 0x65, 0x69, 643 | 0x2e, 0x76, 0x31, 0x22, 0x0d, 0x0a, 0x0b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 644 | 0x73, 0x74, 0x22, 0xda, 0x04, 0x0a, 0x0c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 645 | 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 646 | 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 647 | 0x03, 0x73, 0x68, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x73, 0x68, 648 | 0x61, 0x88, 0x01, 0x01, 0x12, 0x26, 0x0a, 0x0c, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x5f, 0x6c, 649 | 0x61, 0x62, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0b, 0x64, 0x6f, 650 | 0x63, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x08, 651 | 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 652 | 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x09, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 653 | 0x5f, 0x73, 0x68, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x08, 0x6d, 0x6f, 654 | 0x64, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 655 | 0x65, 0x6c, 0x5f, 0x64, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 656 | 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x44, 0x74, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x0a, 0x6d, 0x6f, 657 | 0x64, 0x65, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 658 | 0x2e, 0x74, 0x65, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x54, 0x79, 0x70, 659 | 0x65, 0x52, 0x09, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x36, 0x0a, 0x17, 660 | 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x72, 661 | 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x6d, 662 | 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 663 | 0x65, 0x73, 0x74, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x6e, 0x70, 0x75, 664 | 0x74, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 665 | 0x6d, 0x61, 0x78, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x28, 666 | 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 667 | 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x74, 668 | 0x63, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x31, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 669 | 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x0b, 670 | 0x20, 0x01, 0x28, 0x0d, 0x48, 0x03, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x42, 0x61, 0x74, 0x63, 0x68, 671 | 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x15, 0x6d, 672 | 0x61, 0x78, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 673 | 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x43, 674 | 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x31, 675 | 0x0a, 0x14, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 676 | 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x74, 0x6f, 677 | 0x6b, 0x65, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 678 | 0x73, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x73, 0x68, 0x61, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x64, 0x6f, 679 | 0x63, 0x6b, 0x65, 0x72, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x6d, 680 | 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x6d, 0x61, 0x78, 681 | 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 682 | 0xfc, 0x01, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x23, 0x0a, 0x0d, 683 | 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x73, 0x18, 0x01, 0x20, 684 | 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x43, 0x68, 0x61, 0x72, 685 | 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 686 | 0x65, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x75, 687 | 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 688 | 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 689 | 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x12, 0x30, 0x0a, 0x14, 690 | 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 691 | 0x65, 0x5f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x6b, 0x65, 692 | 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x12, 0x22, 693 | 0x0a, 0x0d, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x18, 694 | 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x71, 0x75, 0x65, 0x75, 0x65, 0x54, 0x69, 0x6d, 0x65, 695 | 0x4e, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x6e, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 696 | 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x69, 697 | 0x6e, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x22, 0x60, 698 | 0x0a, 0x0c, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 699 | 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 700 | 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 701 | 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 702 | 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x18, 703 | 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 704 | 0x22, 0x5d, 0x0a, 0x0d, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 705 | 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 706 | 0x01, 0x20, 0x03, 0x28, 0x02, 0x52, 0x0a, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 707 | 0x73, 0x12, 0x2c, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 708 | 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x65, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 709 | 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 710 | 0x55, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 711 | 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 712 | 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x61, 0x64, 0x64, 0x5f, 713 | 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x02, 714 | 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x61, 0x64, 0x64, 0x53, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 715 | 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x0b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 716 | 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 717 | 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 718 | 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x70, 719 | 0x65, 0x63, 0x69, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x70, 0x65, 720 | 0x63, 0x69, 0x61, 0x6c, 0x12, 0x19, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x04, 0x20, 721 | 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x88, 0x01, 0x01, 0x12, 722 | 0x17, 0x0a, 0x04, 0x73, 0x74, 0x6f, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 723 | 0x04, 0x73, 0x74, 0x6f, 0x70, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, 724 | 0x72, 0x74, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x22, 0x3d, 0x0a, 0x0e, 0x45, 725 | 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 726 | 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 727 | 0x74, 0x65, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x54, 0x6f, 0x6b, 728 | 0x65, 0x6e, 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x2a, 0x59, 0x0a, 0x09, 0x4d, 0x6f, 729 | 0x64, 0x65, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x4f, 0x44, 0x45, 0x4c, 730 | 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4d, 0x42, 0x45, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x10, 731 | 0x00, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x4f, 0x44, 0x45, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 732 | 0x43, 0x4c, 0x41, 0x53, 0x53, 0x49, 0x46, 0x49, 0x45, 0x52, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 733 | 0x4d, 0x4f, 0x44, 0x45, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x52, 0x41, 0x4e, 734 | 0x4b, 0x45, 0x52, 0x10, 0x02, 0x32, 0x3e, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x36, 0x0a, 735 | 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x13, 0x2e, 0x74, 0x65, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x49, 736 | 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x74, 0x65, 0x69, 737 | 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 738 | 0x22, 0x03, 0x90, 0x02, 0x02, 0x32, 0x3d, 0x0a, 0x05, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x12, 0x34, 739 | 0x0a, 0x05, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x12, 0x14, 0x2e, 0x74, 0x65, 0x69, 0x2e, 0x76, 0x31, 740 | 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 741 | 0x74, 0x65, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 742 | 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x45, 0x0a, 0x08, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x69, 0x7a, 0x65, 743 | 0x12, 0x39, 0x0a, 0x08, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x69, 0x7a, 0x65, 0x12, 0x15, 0x2e, 0x74, 744 | 0x65, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 745 | 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x74, 0x65, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 746 | 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x38, 0x5a, 0x36, 0x67, 747 | 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x75, 0x6c, 0x7a, 0x65, 0x61, 748 | 0x69, 0x2d, 0x6f, 0x73, 0x73, 0x2f, 0x6b, 0x6e, 0x6e, 0x2d, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 749 | 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x69, 0x70, 0x62, 0x3b, 750 | 0x74, 0x65, 0x69, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 751 | } 752 | 753 | var ( 754 | file_tei_proto_rawDescOnce sync.Once 755 | file_tei_proto_rawDescData = file_tei_proto_rawDesc 756 | ) 757 | 758 | func file_tei_proto_rawDescGZIP() []byte { 759 | file_tei_proto_rawDescOnce.Do(func() { 760 | file_tei_proto_rawDescData = protoimpl.X.CompressGZIP(file_tei_proto_rawDescData) 761 | }) 762 | return file_tei_proto_rawDescData 763 | } 764 | 765 | var file_tei_proto_enumTypes = make([]protoimpl.EnumInfo, 1) 766 | var file_tei_proto_msgTypes = make([]protoimpl.MessageInfo, 8) 767 | var file_tei_proto_goTypes = []interface{}{ 768 | (ModelType)(0), // 0: tei.v1.ModelType 769 | (*InfoRequest)(nil), // 1: tei.v1.InfoRequest 770 | (*InfoResponse)(nil), // 2: tei.v1.InfoResponse 771 | (*Metadata)(nil), // 3: tei.v1.Metadata 772 | (*EmbedRequest)(nil), // 4: tei.v1.EmbedRequest 773 | (*EmbedResponse)(nil), // 5: tei.v1.EmbedResponse 774 | (*EncodeRequest)(nil), // 6: tei.v1.EncodeRequest 775 | (*SimpleToken)(nil), // 7: tei.v1.SimpleToken 776 | (*EncodeResponse)(nil), // 8: tei.v1.EncodeResponse 777 | } 778 | var file_tei_proto_depIdxs = []int32{ 779 | 0, // 0: tei.v1.InfoResponse.model_type:type_name -> tei.v1.ModelType 780 | 3, // 1: tei.v1.EmbedResponse.metadata:type_name -> tei.v1.Metadata 781 | 7, // 2: tei.v1.EncodeResponse.tokens:type_name -> tei.v1.SimpleToken 782 | 1, // 3: tei.v1.Info.Info:input_type -> tei.v1.InfoRequest 783 | 4, // 4: tei.v1.Embed.Embed:input_type -> tei.v1.EmbedRequest 784 | 6, // 5: tei.v1.Tokenize.Tokenize:input_type -> tei.v1.EncodeRequest 785 | 2, // 6: tei.v1.Info.Info:output_type -> tei.v1.InfoResponse 786 | 5, // 7: tei.v1.Embed.Embed:output_type -> tei.v1.EmbedResponse 787 | 8, // 8: tei.v1.Tokenize.Tokenize:output_type -> tei.v1.EncodeResponse 788 | 6, // [6:9] is the sub-list for method output_type 789 | 3, // [3:6] is the sub-list for method input_type 790 | 3, // [3:3] is the sub-list for extension type_name 791 | 3, // [3:3] is the sub-list for extension extendee 792 | 0, // [0:3] is the sub-list for field type_name 793 | } 794 | 795 | func init() { file_tei_proto_init() } 796 | func file_tei_proto_init() { 797 | if File_tei_proto != nil { 798 | return 799 | } 800 | if !protoimpl.UnsafeEnabled { 801 | file_tei_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 802 | switch v := v.(*InfoRequest); i { 803 | case 0: 804 | return &v.state 805 | case 1: 806 | return &v.sizeCache 807 | case 2: 808 | return &v.unknownFields 809 | default: 810 | return nil 811 | } 812 | } 813 | file_tei_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 814 | switch v := v.(*InfoResponse); i { 815 | case 0: 816 | return &v.state 817 | case 1: 818 | return &v.sizeCache 819 | case 2: 820 | return &v.unknownFields 821 | default: 822 | return nil 823 | } 824 | } 825 | file_tei_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { 826 | switch v := v.(*Metadata); i { 827 | case 0: 828 | return &v.state 829 | case 1: 830 | return &v.sizeCache 831 | case 2: 832 | return &v.unknownFields 833 | default: 834 | return nil 835 | } 836 | } 837 | file_tei_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { 838 | switch v := v.(*EmbedRequest); i { 839 | case 0: 840 | return &v.state 841 | case 1: 842 | return &v.sizeCache 843 | case 2: 844 | return &v.unknownFields 845 | default: 846 | return nil 847 | } 848 | } 849 | file_tei_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { 850 | switch v := v.(*EmbedResponse); i { 851 | case 0: 852 | return &v.state 853 | case 1: 854 | return &v.sizeCache 855 | case 2: 856 | return &v.unknownFields 857 | default: 858 | return nil 859 | } 860 | } 861 | file_tei_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { 862 | switch v := v.(*EncodeRequest); i { 863 | case 0: 864 | return &v.state 865 | case 1: 866 | return &v.sizeCache 867 | case 2: 868 | return &v.unknownFields 869 | default: 870 | return nil 871 | } 872 | } 873 | file_tei_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { 874 | switch v := v.(*SimpleToken); i { 875 | case 0: 876 | return &v.state 877 | case 1: 878 | return &v.sizeCache 879 | case 2: 880 | return &v.unknownFields 881 | default: 882 | return nil 883 | } 884 | } 885 | file_tei_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { 886 | switch v := v.(*EncodeResponse); i { 887 | case 0: 888 | return &v.state 889 | case 1: 890 | return &v.sizeCache 891 | case 2: 892 | return &v.unknownFields 893 | default: 894 | return nil 895 | } 896 | } 897 | } 898 | file_tei_proto_msgTypes[1].OneofWrappers = []interface{}{} 899 | file_tei_proto_msgTypes[6].OneofWrappers = []interface{}{} 900 | type x struct{} 901 | out := protoimpl.TypeBuilder{ 902 | File: protoimpl.DescBuilder{ 903 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 904 | RawDescriptor: file_tei_proto_rawDesc, 905 | NumEnums: 1, 906 | NumMessages: 8, 907 | NumExtensions: 0, 908 | NumServices: 3, 909 | }, 910 | GoTypes: file_tei_proto_goTypes, 911 | DependencyIndexes: file_tei_proto_depIdxs, 912 | EnumInfos: file_tei_proto_enumTypes, 913 | MessageInfos: file_tei_proto_msgTypes, 914 | }.Build() 915 | File_tei_proto = out.File 916 | file_tei_proto_rawDesc = nil 917 | file_tei_proto_goTypes = nil 918 | file_tei_proto_depIdxs = nil 919 | } 920 | -------------------------------------------------------------------------------- /internal/teipb/tei_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.3.0 4 | // - protoc v5.26.1 5 | // source: tei.proto 6 | 7 | package teipb 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.32.0 or later. 19 | const _ = grpc.SupportPackageIsVersion7 20 | 21 | const ( 22 | Info_Info_FullMethodName = "/tei.v1.Info/Info" 23 | ) 24 | 25 | // InfoClient is the client API for Info service. 26 | // 27 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 28 | type InfoClient interface { 29 | Info(ctx context.Context, in *InfoRequest, opts ...grpc.CallOption) (*InfoResponse, error) 30 | } 31 | 32 | type infoClient struct { 33 | cc grpc.ClientConnInterface 34 | } 35 | 36 | func NewInfoClient(cc grpc.ClientConnInterface) InfoClient { 37 | return &infoClient{cc} 38 | } 39 | 40 | func (c *infoClient) Info(ctx context.Context, in *InfoRequest, opts ...grpc.CallOption) (*InfoResponse, error) { 41 | out := new(InfoResponse) 42 | err := c.cc.Invoke(ctx, Info_Info_FullMethodName, in, out, opts...) 43 | if err != nil { 44 | return nil, err 45 | } 46 | return out, nil 47 | } 48 | 49 | // InfoServer is the server API for Info service. 50 | // All implementations must embed UnimplementedInfoServer 51 | // for forward compatibility 52 | type InfoServer interface { 53 | Info(context.Context, *InfoRequest) (*InfoResponse, error) 54 | mustEmbedUnimplementedInfoServer() 55 | } 56 | 57 | // UnimplementedInfoServer must be embedded to have forward compatible implementations. 58 | type UnimplementedInfoServer struct { 59 | } 60 | 61 | func (UnimplementedInfoServer) Info(context.Context, *InfoRequest) (*InfoResponse, error) { 62 | return nil, status.Errorf(codes.Unimplemented, "method Info not implemented") 63 | } 64 | func (UnimplementedInfoServer) mustEmbedUnimplementedInfoServer() {} 65 | 66 | // UnsafeInfoServer may be embedded to opt out of forward compatibility for this service. 67 | // Use of this interface is not recommended, as added methods to InfoServer will 68 | // result in compilation errors. 69 | type UnsafeInfoServer interface { 70 | mustEmbedUnimplementedInfoServer() 71 | } 72 | 73 | func RegisterInfoServer(s grpc.ServiceRegistrar, srv InfoServer) { 74 | s.RegisterService(&Info_ServiceDesc, srv) 75 | } 76 | 77 | func _Info_Info_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 78 | in := new(InfoRequest) 79 | if err := dec(in); err != nil { 80 | return nil, err 81 | } 82 | if interceptor == nil { 83 | return srv.(InfoServer).Info(ctx, in) 84 | } 85 | info := &grpc.UnaryServerInfo{ 86 | Server: srv, 87 | FullMethod: Info_Info_FullMethodName, 88 | } 89 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 90 | return srv.(InfoServer).Info(ctx, req.(*InfoRequest)) 91 | } 92 | return interceptor(ctx, in, info, handler) 93 | } 94 | 95 | // Info_ServiceDesc is the grpc.ServiceDesc for Info service. 96 | // It's only intended for direct use with grpc.RegisterService, 97 | // and not to be introspected or modified (even as a copy) 98 | var Info_ServiceDesc = grpc.ServiceDesc{ 99 | ServiceName: "tei.v1.Info", 100 | HandlerType: (*InfoServer)(nil), 101 | Methods: []grpc.MethodDesc{ 102 | { 103 | MethodName: "Info", 104 | Handler: _Info_Info_Handler, 105 | }, 106 | }, 107 | Streams: []grpc.StreamDesc{}, 108 | Metadata: "tei.proto", 109 | } 110 | 111 | const ( 112 | Embed_Embed_FullMethodName = "/tei.v1.Embed/Embed" 113 | ) 114 | 115 | // EmbedClient is the client API for Embed service. 116 | // 117 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 118 | type EmbedClient interface { 119 | Embed(ctx context.Context, in *EmbedRequest, opts ...grpc.CallOption) (*EmbedResponse, error) 120 | } 121 | 122 | type embedClient struct { 123 | cc grpc.ClientConnInterface 124 | } 125 | 126 | func NewEmbedClient(cc grpc.ClientConnInterface) EmbedClient { 127 | return &embedClient{cc} 128 | } 129 | 130 | func (c *embedClient) Embed(ctx context.Context, in *EmbedRequest, opts ...grpc.CallOption) (*EmbedResponse, error) { 131 | out := new(EmbedResponse) 132 | err := c.cc.Invoke(ctx, Embed_Embed_FullMethodName, in, out, opts...) 133 | if err != nil { 134 | return nil, err 135 | } 136 | return out, nil 137 | } 138 | 139 | // EmbedServer is the server API for Embed service. 140 | // All implementations must embed UnimplementedEmbedServer 141 | // for forward compatibility 142 | type EmbedServer interface { 143 | Embed(context.Context, *EmbedRequest) (*EmbedResponse, error) 144 | mustEmbedUnimplementedEmbedServer() 145 | } 146 | 147 | // UnimplementedEmbedServer must be embedded to have forward compatible implementations. 148 | type UnimplementedEmbedServer struct { 149 | } 150 | 151 | func (UnimplementedEmbedServer) Embed(context.Context, *EmbedRequest) (*EmbedResponse, error) { 152 | return nil, status.Errorf(codes.Unimplemented, "method Embed not implemented") 153 | } 154 | func (UnimplementedEmbedServer) mustEmbedUnimplementedEmbedServer() {} 155 | 156 | // UnsafeEmbedServer may be embedded to opt out of forward compatibility for this service. 157 | // Use of this interface is not recommended, as added methods to EmbedServer will 158 | // result in compilation errors. 159 | type UnsafeEmbedServer interface { 160 | mustEmbedUnimplementedEmbedServer() 161 | } 162 | 163 | func RegisterEmbedServer(s grpc.ServiceRegistrar, srv EmbedServer) { 164 | s.RegisterService(&Embed_ServiceDesc, srv) 165 | } 166 | 167 | func _Embed_Embed_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 168 | in := new(EmbedRequest) 169 | if err := dec(in); err != nil { 170 | return nil, err 171 | } 172 | if interceptor == nil { 173 | return srv.(EmbedServer).Embed(ctx, in) 174 | } 175 | info := &grpc.UnaryServerInfo{ 176 | Server: srv, 177 | FullMethod: Embed_Embed_FullMethodName, 178 | } 179 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 180 | return srv.(EmbedServer).Embed(ctx, req.(*EmbedRequest)) 181 | } 182 | return interceptor(ctx, in, info, handler) 183 | } 184 | 185 | // Embed_ServiceDesc is the grpc.ServiceDesc for Embed service. 186 | // It's only intended for direct use with grpc.RegisterService, 187 | // and not to be introspected or modified (even as a copy) 188 | var Embed_ServiceDesc = grpc.ServiceDesc{ 189 | ServiceName: "tei.v1.Embed", 190 | HandlerType: (*EmbedServer)(nil), 191 | Methods: []grpc.MethodDesc{ 192 | { 193 | MethodName: "Embed", 194 | Handler: _Embed_Embed_Handler, 195 | }, 196 | }, 197 | Streams: []grpc.StreamDesc{}, 198 | Metadata: "tei.proto", 199 | } 200 | 201 | const ( 202 | Tokenize_Tokenize_FullMethodName = "/tei.v1.Tokenize/Tokenize" 203 | ) 204 | 205 | // TokenizeClient is the client API for Tokenize service. 206 | // 207 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 208 | type TokenizeClient interface { 209 | Tokenize(ctx context.Context, in *EncodeRequest, opts ...grpc.CallOption) (*EncodeResponse, error) 210 | } 211 | 212 | type tokenizeClient struct { 213 | cc grpc.ClientConnInterface 214 | } 215 | 216 | func NewTokenizeClient(cc grpc.ClientConnInterface) TokenizeClient { 217 | return &tokenizeClient{cc} 218 | } 219 | 220 | func (c *tokenizeClient) Tokenize(ctx context.Context, in *EncodeRequest, opts ...grpc.CallOption) (*EncodeResponse, error) { 221 | out := new(EncodeResponse) 222 | err := c.cc.Invoke(ctx, Tokenize_Tokenize_FullMethodName, in, out, opts...) 223 | if err != nil { 224 | return nil, err 225 | } 226 | return out, nil 227 | } 228 | 229 | // TokenizeServer is the server API for Tokenize service. 230 | // All implementations must embed UnimplementedTokenizeServer 231 | // for forward compatibility 232 | type TokenizeServer interface { 233 | Tokenize(context.Context, *EncodeRequest) (*EncodeResponse, error) 234 | mustEmbedUnimplementedTokenizeServer() 235 | } 236 | 237 | // UnimplementedTokenizeServer must be embedded to have forward compatible implementations. 238 | type UnimplementedTokenizeServer struct { 239 | } 240 | 241 | func (UnimplementedTokenizeServer) Tokenize(context.Context, *EncodeRequest) (*EncodeResponse, error) { 242 | return nil, status.Errorf(codes.Unimplemented, "method Tokenize not implemented") 243 | } 244 | func (UnimplementedTokenizeServer) mustEmbedUnimplementedTokenizeServer() {} 245 | 246 | // UnsafeTokenizeServer may be embedded to opt out of forward compatibility for this service. 247 | // Use of this interface is not recommended, as added methods to TokenizeServer will 248 | // result in compilation errors. 249 | type UnsafeTokenizeServer interface { 250 | mustEmbedUnimplementedTokenizeServer() 251 | } 252 | 253 | func RegisterTokenizeServer(s grpc.ServiceRegistrar, srv TokenizeServer) { 254 | s.RegisterService(&Tokenize_ServiceDesc, srv) 255 | } 256 | 257 | func _Tokenize_Tokenize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 258 | in := new(EncodeRequest) 259 | if err := dec(in); err != nil { 260 | return nil, err 261 | } 262 | if interceptor == nil { 263 | return srv.(TokenizeServer).Tokenize(ctx, in) 264 | } 265 | info := &grpc.UnaryServerInfo{ 266 | Server: srv, 267 | FullMethod: Tokenize_Tokenize_FullMethodName, 268 | } 269 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 270 | return srv.(TokenizeServer).Tokenize(ctx, req.(*EncodeRequest)) 271 | } 272 | return interceptor(ctx, in, info, handler) 273 | } 274 | 275 | // Tokenize_ServiceDesc is the grpc.ServiceDesc for Tokenize service. 276 | // It's only intended for direct use with grpc.RegisterService, 277 | // and not to be introspected or modified (even as a copy) 278 | var Tokenize_ServiceDesc = grpc.ServiceDesc{ 279 | ServiceName: "tei.v1.Tokenize", 280 | HandlerType: (*TokenizeServer)(nil), 281 | Methods: []grpc.MethodDesc{ 282 | { 283 | MethodName: "Tokenize", 284 | Handler: _Tokenize_Tokenize_Handler, 285 | }, 286 | }, 287 | Streams: []grpc.StreamDesc{}, 288 | Metadata: "tei.proto", 289 | } 290 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/pulzeai-oss/knn-router/cmd" 7 | ) 8 | 9 | func main() { 10 | if err := cmd.Execute(); err != nil { 11 | log.Fatalf("Failed to execute command: %v", err) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /proto/scores/scores.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package scores.v1; 4 | 5 | option go_package = "github.com/pulzeai-oss/knn-router/internal/scorespb;scorespb"; 6 | 7 | message Score { 8 | string target = 1; 9 | float score = 2; 10 | } 11 | 12 | message Point { 13 | string category = 1; 14 | repeated Score scores = 2; 15 | } 16 | -------------------------------------------------------------------------------- /proto/tei/tei.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package tei.v1; 4 | 5 | option go_package = "github.com/pulzeai-oss/knn-router/internal/teipb;teipb"; 6 | 7 | service Info { 8 | rpc Info (InfoRequest) returns (InfoResponse) { 9 | option idempotency_level = IDEMPOTENT; 10 | }; 11 | } 12 | 13 | service Embed { 14 | rpc Embed (EmbedRequest) returns (EmbedResponse); 15 | } 16 | 17 | service Tokenize { 18 | rpc Tokenize (EncodeRequest) returns (EncodeResponse); 19 | } 20 | 21 | message InfoRequest {} 22 | 23 | enum ModelType { 24 | MODEL_TYPE_EMBEDDING = 0; 25 | MODEL_TYPE_CLASSIFIER = 1; 26 | MODEL_TYPE_RERANKER = 2; 27 | } 28 | 29 | message InfoResponse { 30 | string version = 1; 31 | optional string sha = 2; 32 | optional string docker_label = 3; 33 | string model_id = 4; 34 | optional string model_sha = 5; 35 | string model_dtype = 6; 36 | ModelType model_type = 7; 37 | uint32 max_concurrent_requests = 8; 38 | uint32 max_input_length = 9; 39 | uint32 max_batch_tokens = 10; 40 | optional uint32 max_batch_requests = 11; 41 | uint32 max_client_batch_size = 12; 42 | uint32 tokenization_workers = 13; 43 | } 44 | 45 | message Metadata { 46 | uint32 compute_chars = 1; 47 | uint32 compute_tokens = 2; 48 | uint64 total_time_ns = 3; 49 | uint64 tokenization_time_ns = 4; 50 | uint64 queue_time_ns = 5; 51 | uint64 inference_time_ns = 6; 52 | } 53 | 54 | message EmbedRequest { 55 | string inputs = 1; 56 | bool truncate = 2; 57 | bool normalize = 3; 58 | } 59 | 60 | message EmbedResponse { 61 | repeated float embeddings = 1; 62 | Metadata metadata = 2; 63 | } 64 | 65 | message EncodeRequest { 66 | string inputs = 1; 67 | bool add_special_tokens = 2; 68 | } 69 | 70 | message SimpleToken { 71 | uint32 id = 1; 72 | string text = 2; 73 | bool special = 3; 74 | optional uint32 start = 4; 75 | optional uint32 stop = 5; 76 | } 77 | 78 | message EncodeResponse { 79 | repeated SimpleToken tokens = 1; 80 | } 81 | -------------------------------------------------------------------------------- /scripts/gen-artifacts.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euxo pipefail 4 | 5 | ROOT_DIR="$(realpath "$(dirname "$0")/..")" 6 | 7 | _cleanup() { 8 | [[ -z "${TMPDIR:-}" ]] || rm -rf ${TMPDIR} 9 | [[ -z "${QDRANT_CNT:-}" ]] || docker kill ${QDRANT_CNT} 10 | } 11 | trap _cleanup EXIT 12 | 13 | # Parse command line arguments 14 | DISTANCE_METRIC="Cosine" 15 | while [[ $# -gt 0 ]]; do 16 | key="$1" 17 | case $key in 18 | --points-data-path) 19 | POINTS_DATA_PATH="$2" 20 | shift 21 | ;; 22 | --scores-data-path) 23 | SCORES_DATA_PATH="$2" 24 | shift 25 | ;; 26 | --distance-metric) 27 | DISTANCE_METRIC="$2" 28 | shift 29 | ;; 30 | --output-dir) 31 | OUTPUT_DIR="$2" 32 | shift 33 | ;; 34 | *) 35 | # Unknown option 36 | echo "Unknown option: $1" 37 | exit 1 38 | ;; 39 | esac 40 | shift 41 | done 42 | 43 | # Create the output directory 44 | mkdir -p ${OUTPUT_DIR} 45 | 46 | # Generate Bolt DB of targets/scores 47 | go run ${ROOT_DIR}/main.go load --points-data-path ${POINTS_DATA_PATH} --scores-data-path ${SCORES_DATA_PATH} --db-path ${OUTPUT_DIR}/scores.db 48 | 49 | # Generate embeddings.snapshot 50 | TMPDIR=$(mktemp -d) 51 | echo ${TMPDIR} 52 | QDRANT_CNT=$(docker run -d -e QDRANT__STORAGE__STORAGE_PATH=/tmp/storage -e QDRANT__STORAGE__SNAPSHOTS_PATH=/tmp/snapshots -it -p 6335:6333 --rm -u "$(id -u)" -v ${TMPDIR}:/tmp/snapshots ghcr.io/qdrant/qdrant/qdrant:v1.9.0-unprivileged ./qdrant) 53 | 54 | # Wait for Qdrant 55 | timeout 1m bash -c 'until curl -s http://localhost:6335/readyz; do sleep 1; done' 56 | 57 | # Create a collection 58 | curl --fail -X PUT http://localhost:6335/collections/main \ 59 | -H 'Content-Type: application/json' \ 60 | --data-raw "{ 61 | \"vectors\": { 62 | \"size\": $(head -n 1 ${POINTS_DATA_PATH} | jq '.embedding | length'), 63 | \"distance\": \"${DISTANCE_METRIC}\" 64 | } 65 | }" 66 | 67 | # Batch upsert points 68 | jq -c '{id: .point_uid, vector: .embedding, payload: {}}' ${POINTS_DATA_PATH} | split -l 500 - ${TMPDIR}/points_part_ 69 | for f in ${TMPDIR}/points_part_*; do 70 | jq -cs '{operations: [{upsert: {points: .}}]}' ${f} > ${f}.payload 71 | curl -X POST http://localhost:6335/collections/main/points/batch \ 72 | -H 'Content-Type: application/json' \ 73 | --data-binary "@${f}.payload" 74 | done 75 | 76 | # Save snapshot 77 | curl --fail -X POST http://localhost:6335/collections/main/snapshots \ 78 | -H 'Content-Type: application/json' 79 | 80 | # Move snapshot to the output directory 81 | mv ${TMPDIR}/main/main-*.snapshot ${OUTPUT_DIR}/embeddings.snapshot 82 | --------------------------------------------------------------------------------