diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78d4abb..fa5d078 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: steps: # it seems like we're going to eventually want to run these - name: Hello World - run: echo "testing golang" + run: go test ./... # okay, so we're going to need to determine how to get make on our builld image somehow #- name: Test diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..50b758e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,42 @@ +# syntax=docker/dockerfile:1 + +# Build the application from source +FROM --platform=linux/amd64 golang:1.19 AS build-stage + +ENV GO111MODULE=on +ENV API_ADDRESS=0.0.0.0:8082 +ENV INFERENTIAL_DB_USER=usr +ENV INFERENTIAL_DB_PASSWORD=identity +ENV INFERENTIAL_DB_HOST=127.0.0.1 +ENV INFERENTIAL_DB_NAME=identity +ENV INFERENTIAL_DB_PORT=3306 +ENV ENABLE_MIGRATE=true + +WORKDIR /app + +COPY go.mod go.sum ./ +RUN go mod download + +# COPY *.go ./ +COPY . . + +RUN go mod download +# RUN go get ./... +RUN CGO_ENABLED=0 GOOS=linux go build -o /delphi-inferential-service + +# Run the tests in the container +FROM build-stage AS run-test-stage +RUN go test -v ./... + +# Deploy the application binary into a lean image +FROM gcr.io/distroless/base-debian11 AS build-release-stage + +WORKDIR / + +COPY --from=build-stage /delphi-inferential-service /delphi-inferential-service + +EXPOSE 50051 + +USER nonroot:nonroot + +ENTRYPOINT ["/delphi-inferential-service"] \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..56ee3c8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9993091 --- /dev/null +++ b/Makefile @@ -0,0 +1,130 @@ + +# protoc --go_out=. --go_opt=paths=source_relative \ +# --go-grpc_out=. --go-grpc_opt=paths=source_relative \ +# helloworld/helloworld.proto +gen_infer_proto: + protoc --go_out=. --go_opt=paths=source_relative \ + --go-grpc_out=. --go-grpc_opt=paths=source_relative \ + internal/protos/inference/inference.proto + +# protoc -I=proto --go_out=plugins=grpc:proto proto/*.proto + +echo: + python3 internal/protos/inference/test.py + +mod-init: + go mod init github.com/Max-Gabriel-Susman/delphi-inferential-service + go mod tidy + go mod vendor + +mod: + go mod tidy + go mod vendor + +local-build-up: + echo "dockerize this bitch s'il vouz plait" + +local-build-down: + echo "go to sleep" + +local-test: + echo "congrats you're HIV positive!" + +# we're gonna wanna parameterize this bad boi later +local-db-up: + docker run -d --name ms -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password mysql +# docker exec -d ms bash mysql-u root -ppassword # i don't think I actually need this command since I'm not mannually logging in + +local-db-migrate: + echo "is this even necessary for GORM? or is this only for schema first ORMs like sql-c?" + + +# okay so it looks like we've managed to login successfully w/ the script +# now we need to find the right connection string + +# this need a check to make sure that mysql is actuall up +local-db-down: + docker stop ms + docker rm ms + + +# idk but the mod target was breaking +# local-env-up: mod local-db-up local-db-migrate local-build-up local-test +local-env-up: local-db-up local-db-migrate local-build-up local-test + + +local-env-down: local-build-down local-db-down + +local-stop: + docker kill identity + +local-start-with-db: + docker run --name identity -d \ + --network=bridge --rm \ + -e MYSQL_USER=usr \ + -e MYSQL_PASSWORD=identity \ + -e MYSQL_DATABASE=identity \ + -e MYSQL_ALLOW_EMPTY_PASSWORD=yes \ + -p 3306:3306 mysql + + DD_DISABLE=true \ + API_ADDRESS=0.0.0.0:8080 \ + IDENTITY_DB_USER=usr \ + IDENTITY_DB_PASSWORD=identity \ + IDENTITY_DB_HOST=127.0.0.1 \ + IDENTITY_DB_NAME=identity \ + IDENTITY_DB_PORT=3306 \ + ENABLE_MIGRATE=true \ + go run ./cmd/bestir-identity-service/ + + +local-start: + DD_DISABLE=true \ + API_ADDRESS=0.0.0.0:8082 \ + INFERENTIAL_DB_USER=usr \ + INFERENTIAL_DB_PASSWORD=identity \ + INFERENTIAL_DB_HOST=127.0.0.1 \ + INFERENTIAL_DB_NAME=identity \ + INFERENTIAL_DB_PORT=3306 \ + ENABLE_MIGRATE=true \ + go run ./main.go + +local-restart: local-stop local-start + +healthcheck-textgen: + echo "turn your head and cough" + +# pb-gen-tg: +# protoc --go_out=. --go_opt=textgeneration/pb/textgeneration \ +# --go-grpc_out=. --go-grpc_opt=paths=./textgeneration/pb/textgeneration \ +# textgeneration/pb/textGenerationService.proto + +# pb-gen-tg: +# protoc --proto_path=proto textgeneration/pb/*.proto --go_out=textgeneration/pb/textGenerationService --go-grpc_out=textgeneration/pb/textGenerationService + +build: + docker build --tag delphi-model-service . + +# docker build --tag brometheus/delphi-inferential-service:v0.1.0 . +# docker build --tag brometheus/delphi-inferential-service:v0.2.0 . + +run: + docker run \ + -e API_ADDRESS=0.0.0.0:8082 \ + -e INFERENTIAL_DB_USER=usr \ + -e INFERENTIAL_DB_PASSWORD=identity \ + -e INFERENTIAL_DB_HOST=127.0.0.1 \ + -e INFERENTIAL_DB_NAME=identity \ + -e INFERENTIAL_DB_PORT=3306 \ + -e ENABLE_MIGRATE=true \ + -p 50054:50054 \ + brometheus/delphi-inferential-service:v0.4.5 + +push: + docker push brometheus/delphi-model-service:tagname + +update: + docker build --tag brometheus/delphi-inferential-service:v0.4.5 . + docker push brometheus/delphi-inferential-service:v0.4.5 + +# docker push brometheus/delphi-inferential-service:v0.1.0 \ No newline at end of file diff --git a/Makefile.project b/Makefile.project new file mode 100644 index 0000000..e69de29 diff --git a/Makefile.vars b/Makefile.vars new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md index e69de29..0a0cf42 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,5 @@ +### Delphi Inferential Service + +## TODOs: + +`* Implement tensor parallelism for inference jobs \ No newline at end of file diff --git a/docker/testing/.env b/docker/testing/.env new file mode 100644 index 0000000..e69de29 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f93dd8a --- /dev/null +++ b/go.mod @@ -0,0 +1,20 @@ +module github.com/Max-Gabriel-Susman/delphi-inferential-service + +go 1.19 + +require ( + github.com/aws/aws-sdk-go v1.46.1 + github.com/google/go-querystring v1.1.0 + google.golang.org/grpc v1.58.2 + google.golang.org/protobuf v1.31.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..bedc9d2 --- /dev/null +++ b/go.sum @@ -0,0 +1,66 @@ +github.com/aws/aws-sdk-go v1.46.1 h1:U26quvBWFZMQuultLw5tloW4GnmWaChEwMZNq8uYatw= +github.com/aws/aws-sdk-go v1.46.1/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= +google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/greeter-service/Makefile b/greeter-service/Makefile deleted file mode 100644 index 1ce2e0d..0000000 --- a/greeter-service/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# -# Copyright 2019 The Cloud Robotics Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -HOST_SYSTEM = $(shell uname | cut -f 1 -d_) -SYSTEM ?= $(HOST_SYSTEM) -CXX = g++ -CPPFLAGS += `pkg-config --cflags protobuf grpc` -CXXFLAGS += -std=c++11 -I . -ifeq ($(SYSTEM),Darwin) -LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ - -lgrpc++_reflection\ - -ldl -else -LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ - -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ - -ldl -endif -PROTOC = protoc -GRPC_CPP_PLUGIN = grpc_cpp_plugin -GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` - -PROTOS_PATH = ./proto/ - -vpath %.proto $(PROTOS_PATH) - -all: greeter-server greeter-client - -greeter-server: helloworld.pb.o helloworld.grpc.pb.o server/server.o - $(CXX) $^ $(LDFLAGS) -o $@ - -greeter-client: helloworld.pb.o helloworld.grpc.pb.o client/client.o - $(CXX) $^ $(LDFLAGS) -o $@ - -.PRECIOUS: %.grpc.pb.cc -%.grpc.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< - -.PRECIOUS: %.pb.cc -%.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< - -clean: - rm -f *.o client/*.o server/*.o *.pb *.pb.cc *.pb.h diff --git a/greeter-service/client/Dockerfile b/greeter-service/client/Dockerfile deleted file mode 100644 index 05c2494..0000000 --- a/greeter-service/client/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM grpc/cxx:1.12.0 - -WORKDIR /data - -COPY client/client.cc ./client/ -COPY proto/helloworld.proto ./proto/ -COPY Makefile ./ - -RUN make greeter-client && make clean - -CMD ["./greeter-client"] diff --git a/greeter-service/client/client.cc b/greeter-service/client/client.cc deleted file mode 100644 index ca81c7b..0000000 --- a/greeter-service/client/client.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* - * - * Copyright 2019 The Cloud Robotics Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include -#include - -#include - -#include "helloworld.grpc.pb.h" - -using grpc::Channel; -using grpc::ChannelCredentials; -using grpc::ClientContext; -using grpc::Status; -using helloworld::Greeter; -using helloworld::HelloReply; -using helloworld::HelloRequest; - -class GreeterClient { - public: - GreeterClient(std::shared_ptr channel) - : stub_(Greeter::NewStub(channel)) {} - - // Assembles the client's payload, sends it and presents the response back - // from the server. - std::string SayHello(const std::string& user) { - // Data we are sending to the server. - HelloRequest request; - request.set_name(user); - - // Container for the data we expect from the server. - HelloReply reply; - - // Context for the client. It could be used to convey extra information to - // the server and/or tweak certain RPC behaviors. - ClientContext context; - - // The actual RPC. - Status status = stub_->SayHello(&context, request, &reply); - - // Act upon its status. - if (status.ok()) { - return reply.message(); - } else { - std::cout << status.error_code() << ": " << status.error_message() - << std::endl; - return "RPC failed"; - } - } - - private: - std::unique_ptr stub_; -}; - -int main(int argc, char** argv) { - if (argc < 2) { - const std::string client_path(argv[0]); - std::cout << "Usage:" << std::endl; - std::cout << " " << client_path << " []" - << std::endl; - std::cout << "Example:" << std::endl; - std::cout << " " << client_path - << " www.endpoints.${PROJECT_ID}.cloud.goog:443" << std::endl; - return 0; - } - - // The first parameter is the server's address, optionally containing the - // port. - std::string grpc_endpoint(argv[1]); - if (grpc_endpoint.find(":") == std::string::npos) { - // Set the default port of the server. - grpc_endpoint += ":50051"; - } - - // The optional second parameter is the name to be sent to the server. - std::string name("world"); - if (argc >= 3) { - name = argv[2]; - } - - std::cout << "Sending request to " << grpc_endpoint << " ..." << std::endl; - - // We are communicating via SSL to the endpoint service using the credentials - // of the user or robot running the client. - // We don't use credentials when connecting to localhost for testing. - std::shared_ptr channel_creds; - if (grpc_endpoint.find("localhost:") == 0 || - grpc_endpoint.find("127.0.0.1:") == 0) { - channel_creds = grpc::InsecureChannelCredentials(); - } else { - channel_creds = grpc::GoogleDefaultCredentials(); - } - - GreeterClient greeter(grpc::CreateChannel(grpc_endpoint, channel_creds)); - std::string user(name); - std::string reply = greeter.SayHello(user); - std::cout << "Greeter received: " << reply << std::endl; - - return 0; -} diff --git a/greeter-service/deploy.sh b/greeter-service/deploy.sh deleted file mode 100755 index bb12493..0000000 --- a/greeter-service/deploy.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -# -# Copyright 2019 The Cloud Robotics Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o pipefail -o errexit -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd ${DIR} - -function die { - echo "$1" >&2 - exit 1 -} - -function push_image { - local target=$1 - - docker build -f "${target}/Dockerfile" -t "greeter-${target}" . - docker tag "greeter-${target}" "gcr.io/${PROJECT_ID}/greeter-${target}" - docker push "gcr.io/${PROJECT_ID}/greeter-${target}" -} - -function create_config { - cat greeter-server.yaml.tmpl | envsubst >greeter-server.yaml -} - -# public functions -function push_client { - push_image client -} - -function update_config { - create_config - kubectl apply -f greeter-server.yaml -} - -function update_server { - push_image server - kubectl delete pod -l 'app=greeter-server-app' - update_config -} - -function create { - push_image server - push_client - update_config -} - -function delete { - create_config - kubectl delete -f greeter-server.yaml -} - -# main -if [[ -z ${PROJECT_ID} ]]; then - die "Set PROJECT_ID first: export PROJECT_ID=[GCP project id]" -fi - -if [[ ! "$1" =~ ^(create|delete|update_config|update_server|push_client)$ ]]; then - die "Usage: $0 {create|delete|update_config|update_server|push_client}" -fi - -# call arguments verbatim: -"$@" diff --git a/greeter-service/greeter-server.yaml.tmpl b/greeter-service/greeter-server.yaml.tmpl deleted file mode 100644 index 7b16bcd..0000000 --- a/greeter-service/greeter-server.yaml.tmpl +++ /dev/null @@ -1,58 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: greeter-server-ingress - annotations: - nginx.ingress.kubernetes.io/backend-protocol: GRPC - nginx.ingress.kubernetes.io/auth-url: "http://token-vendor.default.svc.cluster.local/apis/core.token-vendor/v1/token.verify?robots=true" -spec: - ingressClassName: nginx - rules: - - host: "www.endpoints.${PROJECT_ID}.cloud.goog" - http: - paths: # must match the namespace and service name in the proto - - path: /helloworld.Greeter/ - pathType: Prefix - backend: - service: - name: greeter-server-service - # must match the port used in server.cc - port: - number: 50051 ---- -apiVersion: v1 -kind: Service -metadata: - name: greeter-server-service -spec: - ports: - - # optional descriptive name for the service port - name: grpc-port - # must match the service port specified in ingress - port: 50051 - # the selector is used to link pods to services - selector: - app: greeter-server-app ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: greeter-server -spec: - replicas: 1 - # all pods matching this selector belong to this deployment - selector: - matchLabels: - app: greeter-server-app - template: - metadata: - # the other side of the link between services and pods - labels: - app: greeter-server-app - spec: - containers: - - name: greeter-server - image: "gcr.io/${PROJECT_ID}/greeter-server:latest" - ports: - # must match the port of the service - - containerPort: 50051 diff --git a/greeter-service/proto/helloworld.proto b/greeter-service/proto/helloworld.proto deleted file mode 100644 index 8fb1014..0000000 --- a/greeter-service/proto/helloworld.proto +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2019 The Cloud Robotics Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting. - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings. -message HelloReply { - string message = 1; -} diff --git a/greeter-service/server/Dockerfile b/greeter-service/server/Dockerfile deleted file mode 100644 index 0ed0358..0000000 --- a/greeter-service/server/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM grpc/cxx:1.12.0 - -WORKDIR /data - -COPY server/server.cc ./server/ -COPY proto/helloworld.proto ./proto/ -COPY Makefile ./ - -RUN make greeter-server && make clean - -CMD ["./greeter-server"] diff --git a/greeter-service/server/server.cc b/greeter-service/server/server.cc deleted file mode 100644 index 66f667c..0000000 --- a/greeter-service/server/server.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright 2019 The Cloud Robotics Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "helloworld.grpc.pb.h" - -using grpc::Server; -using grpc::ServerBuilder; -using grpc::ServerContext; -using grpc::Status; -using helloworld::Greeter; -using helloworld::HelloReply; -using helloworld::HelloRequest; - -// The gRPC server is defined globally so that SIGTERM handler can shut it -// down when Kubernetes stops the process. -std::unique_ptr server; - -// Logic and data behind the server's behavior. -class GreeterServiceImpl final : public Greeter::Service { - Status SayHello(ServerContext* context, const HelloRequest* request, - HelloReply* reply) override { - std::cout << "Received request: " << request->ShortDebugString() - << std::endl; - std::string prefix("Hello "); - reply->set_message(prefix + request->name()); - return Status::OK; - } -}; - -void RunServer() { - std::string server_address("0.0.0.0:50051"); - GreeterServiceImpl service; - - ServerBuilder builder; - // Listen on the given address without any authentication mechanism. Cloud - // Robotics Core ensures that clients are authenticated. - builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); - // Register "service" as the instance through which we'll communicate with - // clients. In this case it corresponds to a *synchronous* service. - builder.RegisterService(&service); - // Finally assemble the server. - server = builder.BuildAndStart(); - std::cout << "Server listening on " << server_address << std::endl; - - std::signal(SIGTERM, [](int) { - // When SIGTERM is received, shutdown the gRPC server. - server->Shutdown(); - }); - - // Wait for the server to shutdown. - server->Wait(); -} - -int main(int argc, char** argv) { - RunServer(); - - return 0; -} diff --git a/internal/clients/openai/client.go b/internal/clients/openai/client.go new file mode 100644 index 0000000..e19fb31 --- /dev/null +++ b/internal/clients/openai/client.go @@ -0,0 +1,81 @@ +package openai + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + + "github.com/google/go-querystring/query" +) + +type Client struct { + apiKey string + Organization string +} + +// NewClient creates a new client +func NewClient(apiKey string, organization string) *Client { + return &Client{ + apiKey: apiKey, + Organization: organization, + } +} + +// Post makes a post request +func (c *Client) Post(url string, input interface{}) (response []byte, err error) { + response = make([]byte, 0) + + rJson, err := json.Marshal(input) + if err != nil { + return response, err + } + + resp, err := c.Call(http.MethodPost, url, bytes.NewReader(rJson)) + if err != nil { + return response, err + } + defer resp.Body.Close() + + response, err = io.ReadAll(resp.Body) + return response, err +} + +// Get makes a get request +func (c *Client) Get(url string, input interface{}) (response []byte, err error) { + if input != nil { + vals, _ := query.Values(input) + query := vals.Encode() + + if query != "" { + url += "?" + query + } + } + + resp, err := c.Call(http.MethodGet, url, nil) + if err != nil { + return response, err + } + defer resp.Body.Close() + + response, err = io.ReadAll(resp.Body) + return response, err +} + +// Call makes a request +func (c *Client) Call(method string, url string, body io.Reader) (response *http.Response, err error) { + req, err := http.NewRequest(method, url, body) + if err != nil { + return response, err + } + + req.Header.Add("Authorization", "Bearer "+c.apiKey) + req.Header.Add("Content-Type", "application/json") + if c.Organization != "" { + req.Header.Add("OpenAI-Organization", c.Organization) + } + + client := &http.Client{} + resp, err := client.Do(req) + return resp, err +} diff --git a/internal/clients/openai/completions.go b/internal/clients/openai/completions.go new file mode 100644 index 0000000..1913abe --- /dev/null +++ b/internal/clients/openai/completions.go @@ -0,0 +1,83 @@ +package openai + +import ( + "encoding/json" + "fmt" +) + +const COMPLETIONS_URL = "https://api.openai.com/v1/chat/completions" + +type CreateCompletionsRequest struct { + Model string `json:"model,omitempty"` + Messages []Message `json:"messages,omitempty"` + Prompt []string `json:"prompt,omitempty"` + Suffix string `json:"suffix,omitempty"` + MaxTokens int `json:"max_tokens,omitempty"` + Temperature float64 `json:"temperature,omitempty"` + TopP float64 `json:"top_p,omitempty"` + N int `json:"n,omitempty"` + Stream bool `json:"stream,omitempty"` + LogProbs int `json:"logprobs,omitempty"` + Echo bool `json:"echo,omitempty"` + Stop []string `json:"stop,omitempty"` + PresencePenalty float64 `json:"presence_penalty,omitempty"` + FrequencyPenalty float64 `json:"frequency_penalty,omitempty"` + BestOf int `json:"best_of,omitempty"` + LogitBias map[string]string `json:"logit_bias,omitempty"` + User string `json:"user,omitempty"` +} + +func (c *Client) CreateCompletionsRaw(r CreateCompletionsRequest) ([]byte, error) { + return c.Post(COMPLETIONS_URL, r) +} + +func (c *Client) CreateCompletions(r CreateCompletionsRequest) (response CreateCompletionsResponse, err error) { + raw, err := c.CreateCompletionsRaw(r) + if err != nil { + return response, err + } + + err = json.Unmarshal(raw, &response) + return response, err +} + +type CreateCompletionsResponse struct { + ID string `json:"id,omitempty"` + Object string `json:"object,omitempty"` + Created int `json:"created,omitempty"` + Model string `json:"model,omitempty"` + Choices []struct { + Message struct { + Role string `json:"role,omitempty"` + Content string `json:"content,omitempty"` + } `json:"message"` + Text string `json:"text,omitempty"` + Index int `json:"index,omitempty"` + Logprobs interface{} `json:"logprobs,omitempty"` + FinishReason string `json:"finish_reason,omitempty"` + } `json:"choices,omitempty"` + Usage struct { + PromptTokens int `json:"prompt_tokens,omitempty"` + CompletionTokens int `json:"completion_tokens,omitempty"` + TotalTokens int `json:"total_tokens,omitempty"` + } `json:"usage,omitempty"` + + Error *Error `json:"error,omitempty"` +} + +// Error is the error standard response from the API +type Error struct { + Message string `json:"message,omitempty"` + Type string `json:"type,omitempty"` + Param interface{} `json:"param,omitempty"` + Code interface{} `json:"code,omitempty"` +} + +func (e *Error) Error() string { + return fmt.Sprintf("%s: %s", e.Code, e.Message) +} + +type Message struct { + Role string `json:"role,omitempty"` + Content string `json:"content,omitempty"` +} diff --git a/internal/textgeneration/generate.go b/internal/textgeneration/generate.go new file mode 100644 index 0000000..6586cb7 --- /dev/null +++ b/internal/textgeneration/generate.go @@ -0,0 +1,37 @@ +package textgeneration + +import ( + "context" + "fmt" + "log" + + "github.com/Max-Gabriel-Susman/delphi-inferential-service/internal/clients/openai" + pb "github.com/Max-Gabriel-Susman/delphi-inferential-service/textgeneration" +) + +// SayHello implements helloworld.GreeterServer +func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { + fmt.Println("guys it's me") + log.Printf("Received: %v", in.GetName()) + r := openai.CreateCompletionsRequest{ + Model: "gpt-3.5-turbo", + Messages: []openai.Message{ + { + Role: "user", + Content: in.GetName(), + }, + }, + Temperature: 0.7, + } + + completions, err := s.OpenAIClient.CreateCompletions(r) + if err != nil { + panic(err) + } + + fmt.Println(completions) + + reply := &pb.HelloReply{Message: completions.Choices[0].Message.Content} + + return reply, nil +} diff --git a/internal/textgeneration/generate_test.go b/internal/textgeneration/generate_test.go new file mode 100644 index 0000000..f2153fb --- /dev/null +++ b/internal/textgeneration/generate_test.go @@ -0,0 +1,9 @@ +package textgeneration_test + +import "testing" + +func TestGenerate(t *testing.T) { + t.Run("test", func(t *testing.T) { + t.Parallel() + }) +} diff --git a/internal/textgeneration/server.go b/internal/textgeneration/server.go new file mode 100644 index 0000000..f1cd333 --- /dev/null +++ b/internal/textgeneration/server.go @@ -0,0 +1,41 @@ +package textgeneration + +import ( + "context" + "flag" + + "github.com/Max-Gabriel-Susman/delphi-inferential-service/internal/clients/openai" + pb "github.com/Max-Gabriel-Susman/delphi-inferential-service/textgeneration" +) + +const defaultName = "world" + +var ( + // we need to parameterize and resolve these addr redundancies l8r + // addr = flag.String("addr", "10.96.0.3:50052", "the address to connect to") + // addr = flag.String("addr", "10.100.0.3:50052", "the address to connect to") + addr = flag.String("addr", "localhost:50053", "the address to connect to") + name = flag.String("name", defaultName, "Name to greet") +) + +type Server interface { + SayHello(context.Context, *pb.HelloRequest) (*pb.HelloReply, error) + Decode(context.Context, *pb.HelloRequest) (*pb.HelloReply, error) +} + +type server struct { + pb.UnimplementedGreeterServer + OpenAIClient *openai.Client +} + +type TextGenerationServer struct { + Server server +} + +func NewTextGenerationServer(openaiClient *openai.Client) *TextGenerationServer { + return &TextGenerationServer{ + Server: server{ + OpenAIClient: openaiClient, + }, + } +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..5a004c8 --- /dev/null +++ b/main.go @@ -0,0 +1,152 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net" + "os" + "os/signal" + "syscall" + + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" + + "github.com/Max-Gabriel-Susman/delphi-inferential-service/internal/clients/openai" + tg "github.com/Max-Gabriel-Susman/delphi-inferential-service/internal/textgeneration" + pb "github.com/Max-Gabriel-Susman/delphi-inferential-service/textgeneration" +) + +const ( + exitCodeErr = 1 + exitCodeInterrupt = 2 +) + +var port = flag.Int("port", 50054, "The server port") // actual port dictation + +func main() { + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + signalChan := make(chan os.Signal, 1) + signal.Notify(signalChan, os.Interrupt) + defer func() { + signal.Stop(signalChan) + cancel() + }() + go func() { + select { + case <-signalChan: // first signal, cancel context + cancel() + case <-ctx.Done(): + } + <-signalChan // second signal, hard exit + os.Exit(exitCodeInterrupt) + }() + if err := run(ctx, os.Args); err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(exitCodeErr) + } +} + +func run(ctx context.Context, _ []string) error { + // awsCfg, err := aws.NewConfig(ctx) + // if err != nil { + // return errors.Wrap(err, "could not create aws sdk config") + // } + + // var cfg struct { + // OpenAI struct { + // APIKey string `env:""` + // APIOrg string `` + // } + // } + // if err := env.Parse(&cfg); err != nil { + // return errors.Wrap(err, "parsing configuration") + // } + apiKey := os.Getenv("API_KEY") // we'll want to get from SSM later + organization := os.Getenv("api-org") + openaiClient := openai.NewClient(apiKey, organization) + + // Start GRPC Service + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + tgs := tg.NewTextGenerationServer(openaiClient) + pb.RegisterGreeterServer(s, &tgs.Server) + log.Printf("server listening at %v", lis.Addr()) + + // register the reflection service which allows clients to determine the methods + // for this gRPC service + reflection.Register(s) + + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } + + sc := make(chan os.Signal, 1) + signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) + <-sc + + return nil +} + +// func Sessions() (*session.Session, error) { +// sess, err := session.NewSession() +// svc := session.Must(sess, err) +// return svc, err +// } + +// func NewSSMClient() *SSM { +// // Create AWS Session +// sess, err := Sessions() +// if err != nil { +// log.Println(err) +// return nil +// } +// ssmsvc := &SSM{ssm.New(sess)} +// // Return SSM client +// return ssmsvc +// } + +// type Param struct { +// Name string +// WithDecryption bool +// ssmsvc *SSM +// } + +// //Param creates the struct for querying the param store +// func (s *SSM) Param(name string, decryption bool) *Param { +// return &Param{ +// Name: name, +// WithDecryption: decryption, +// ssmsvc: s, +// } +// } + +// func (p *Param) GetValue() (string, error) { +// ssmsvc := p.ssmsvc.client +// parameter, err := ssmsvc.GetParameter(&ssm.GetParameterInput{ +// Name: &p.Name, +// WithDecryption: &p.WithDecryption, +// }) +// if err != nil { +// return "", err +// } +// value := *parameter.Parameter.Value +// return value, nil +// } + +// // ssmsvc := NewSSMClient() +// // apiKey, err := ssmsvc.Param("myparam", true).GetValue() +// // if err != nil { +// // log.Println(err) +// // } +// // log.Println(apiKey) +// // organization, err := ssmsvc.Param("myparam", true).GetValue() +// // if err != nil { +// // log.Println(err) +// // } +// // log.Println(organization) diff --git a/textgeneration/Makefile b/textgeneration/Makefile new file mode 100644 index 0000000..7a67396 --- /dev/null +++ b/textgeneration/Makefile @@ -0,0 +1,10 @@ + +generate: + protoc --go_out=. --go_opt=paths=source_relative \ + --go-grpc_out=. --go-grpc_opt=paths=source_relative \ + textgeneration.proto + +protoc: + protoc --go_out=. --go_opt=paths=source_relative \ + --go-grpc_out=. --go-grpc_opt=paths=source_relative \ + textgeneration.proto \ No newline at end of file diff --git a/textgeneration/textgeneration.pb.go b/textgeneration/textgeneration.pb.go new file mode 100644 index 0000000..7b08f6e --- /dev/null +++ b/textgeneration/textgeneration.pb.go @@ -0,0 +1,841 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v4.24.3 +// source: textgeneration.proto + +package textgeneration + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type FinishReason int32 + +const ( + FinishReason_FINISH_REASON_LENGTH FinishReason = 0 + FinishReason_FINISH_REASON_EOS_TOKEN FinishReason = 1 + FinishReason_FINISH_REASON_STOP_SEQUENCE FinishReason = 2 +) + +// Enum value maps for FinishReason. +var ( + FinishReason_name = map[int32]string{ + 0: "FINISH_REASON_LENGTH", + 1: "FINISH_REASON_EOS_TOKEN", + 2: "FINISH_REASON_STOP_SEQUENCE", + } + FinishReason_value = map[string]int32{ + "FINISH_REASON_LENGTH": 0, + "FINISH_REASON_EOS_TOKEN": 1, + "FINISH_REASON_STOP_SEQUENCE": 2, + } +) + +func (x FinishReason) Enum() *FinishReason { + p := new(FinishReason) + *p = x + return p +} + +func (x FinishReason) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (FinishReason) Descriptor() protoreflect.EnumDescriptor { + return file_textgeneration_proto_enumTypes[0].Descriptor() +} + +func (FinishReason) Type() protoreflect.EnumType { + return &file_textgeneration_proto_enumTypes[0] +} + +func (x FinishReason) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use FinishReason.Descriptor instead. +func (FinishReason) EnumDescriptor() ([]byte, []int) { + return file_textgeneration_proto_rawDescGZIP(), []int{0} +} + +// The request message containing the user's name. +type HelloRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *HelloRequest) Reset() { + *x = HelloRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_textgeneration_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HelloRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HelloRequest) ProtoMessage() {} + +func (x *HelloRequest) ProtoReflect() protoreflect.Message { + mi := &file_textgeneration_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead. +func (*HelloRequest) Descriptor() ([]byte, []int) { + return file_textgeneration_proto_rawDescGZIP(), []int{0} +} + +func (x *HelloRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// The response message containing the greetings +type HelloReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *HelloReply) Reset() { + *x = HelloReply{} + if protoimpl.UnsafeEnabled { + mi := &file_textgeneration_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HelloReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HelloReply) ProtoMessage() {} + +func (x *HelloReply) ProtoReflect() protoreflect.Message { + mi := &file_textgeneration_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HelloReply.ProtoReflect.Descriptor instead. +func (*HelloReply) Descriptor() ([]byte, []int) { + return file_textgeneration_proto_rawDescGZIP(), []int{1} +} + +func (x *HelloReply) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type PrefillTokens struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + /// Prefill Token IDs + Ids []uint32 `protobuf:"varint,1,rep,packed,name=ids,proto3" json:"ids,omitempty"` + /// Prefill Logprobs + Logprobs []float32 `protobuf:"fixed32,2,rep,packed,name=logprobs,proto3" json:"logprobs,omitempty"` + /// Prefill tokens + Texts []string `protobuf:"bytes,3,rep,name=texts,proto3" json:"texts,omitempty"` +} + +func (x *PrefillTokens) Reset() { + *x = PrefillTokens{} + if protoimpl.UnsafeEnabled { + mi := &file_textgeneration_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PrefillTokens) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PrefillTokens) ProtoMessage() {} + +func (x *PrefillTokens) ProtoReflect() protoreflect.Message { + mi := &file_textgeneration_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PrefillTokens.ProtoReflect.Descriptor instead. +func (*PrefillTokens) Descriptor() ([]byte, []int) { + return file_textgeneration_proto_rawDescGZIP(), []int{2} +} + +func (x *PrefillTokens) GetIds() []uint32 { + if x != nil { + return x.Ids + } + return nil +} + +func (x *PrefillTokens) GetLogprobs() []float32 { + if x != nil { + return x.Logprobs + } + return nil +} + +func (x *PrefillTokens) GetTexts() []string { + if x != nil { + return x.Texts + } + return nil +} + +type CachedBatch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + /// Batch ID + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + /// Individual requests ids + RequestIds []uint64 `protobuf:"varint,2,rep,packed,name=request_ids,json=requestIds,proto3" json:"request_ids,omitempty"` + /// Batch size (==len(requests)) + Size uint32 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` + /// Maximum number of tokens this batch will grow to + MaxTokens uint32 `protobuf:"varint,4,opt,name=max_tokens,json=maxTokens,proto3" json:"max_tokens,omitempty"` +} + +func (x *CachedBatch) Reset() { + *x = CachedBatch{} + if protoimpl.UnsafeEnabled { + mi := &file_textgeneration_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CachedBatch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CachedBatch) ProtoMessage() {} + +func (x *CachedBatch) ProtoReflect() protoreflect.Message { + mi := &file_textgeneration_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CachedBatch.ProtoReflect.Descriptor instead. +func (*CachedBatch) Descriptor() ([]byte, []int) { + return file_textgeneration_proto_rawDescGZIP(), []int{3} +} + +func (x *CachedBatch) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *CachedBatch) GetRequestIds() []uint64 { + if x != nil { + return x.RequestIds + } + return nil +} + +func (x *CachedBatch) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *CachedBatch) GetMaxTokens() uint32 { + if x != nil { + return x.MaxTokens + } + return 0 +} + +type GeneratedText struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + /// Output + Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` + /// Number of generated tokens + GeneratedTokens uint32 `protobuf:"varint,2,opt,name=generated_tokens,json=generatedTokens,proto3" json:"generated_tokens,omitempty"` + /// Finish reason + FinishReason FinishReason `protobuf:"varint,3,opt,name=finish_reason,json=finishReason,proto3,enum=FinishReason" json:"finish_reason,omitempty"` + /// Seed + Seed *uint64 `protobuf:"varint,4,opt,name=seed,proto3,oneof" json:"seed,omitempty"` +} + +func (x *GeneratedText) Reset() { + *x = GeneratedText{} + if protoimpl.UnsafeEnabled { + mi := &file_textgeneration_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GeneratedText) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GeneratedText) ProtoMessage() {} + +func (x *GeneratedText) ProtoReflect() protoreflect.Message { + mi := &file_textgeneration_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GeneratedText.ProtoReflect.Descriptor instead. +func (*GeneratedText) Descriptor() ([]byte, []int) { + return file_textgeneration_proto_rawDescGZIP(), []int{4} +} + +func (x *GeneratedText) GetText() string { + if x != nil { + return x.Text + } + return "" +} + +func (x *GeneratedText) GetGeneratedTokens() uint32 { + if x != nil { + return x.GeneratedTokens + } + return 0 +} + +func (x *GeneratedText) GetFinishReason() FinishReason { + if x != nil { + return x.FinishReason + } + return FinishReason_FINISH_REASON_LENGTH +} + +func (x *GeneratedText) GetSeed() uint64 { + if x != nil && x.Seed != nil { + return *x.Seed + } + return 0 +} + +type Generation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + /// Request ID + RequestId uint64 `protobuf:"varint,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + /// Prefill tokens (optional) + PrefillTokens *PrefillTokens `protobuf:"bytes,2,opt,name=prefill_tokens,json=prefillTokens,proto3" json:"prefill_tokens,omitempty"` + /// Token ID + TokenId uint32 `protobuf:"varint,3,opt,name=token_id,json=tokenId,proto3" json:"token_id,omitempty"` + /// Logprob + TokenLogprob float32 `protobuf:"fixed32,4,opt,name=token_logprob,json=tokenLogprob,proto3" json:"token_logprob,omitempty"` + /// Text + TokenText string `protobuf:"bytes,5,opt,name=token_text,json=tokenText,proto3" json:"token_text,omitempty"` + /// Is it a special token + TokenIsSpecial bool `protobuf:"varint,6,opt,name=token_is_special,json=tokenIsSpecial,proto3" json:"token_is_special,omitempty"` + /// Complete generated text + GeneratedText *GeneratedText `protobuf:"bytes,7,opt,name=generated_text,json=generatedText,proto3,oneof" json:"generated_text,omitempty"` +} + +func (x *Generation) Reset() { + *x = Generation{} + if protoimpl.UnsafeEnabled { + mi := &file_textgeneration_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Generation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Generation) ProtoMessage() {} + +func (x *Generation) ProtoReflect() protoreflect.Message { + mi := &file_textgeneration_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Generation.ProtoReflect.Descriptor instead. +func (*Generation) Descriptor() ([]byte, []int) { + return file_textgeneration_proto_rawDescGZIP(), []int{5} +} + +func (x *Generation) GetRequestId() uint64 { + if x != nil { + return x.RequestId + } + return 0 +} + +func (x *Generation) GetPrefillTokens() *PrefillTokens { + if x != nil { + return x.PrefillTokens + } + return nil +} + +func (x *Generation) GetTokenId() uint32 { + if x != nil { + return x.TokenId + } + return 0 +} + +func (x *Generation) GetTokenLogprob() float32 { + if x != nil { + return x.TokenLogprob + } + return 0 +} + +func (x *Generation) GetTokenText() string { + if x != nil { + return x.TokenText + } + return "" +} + +func (x *Generation) GetTokenIsSpecial() bool { + if x != nil { + return x.TokenIsSpecial + } + return false +} + +func (x *Generation) GetGeneratedText() *GeneratedText { + if x != nil { + return x.GeneratedText + } + return nil +} + +type DecodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + /// Cached batches + Batches []*CachedBatch `protobuf:"bytes,1,rep,name=batches,proto3" json:"batches,omitempty"` +} + +func (x *DecodeRequest) Reset() { + *x = DecodeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_textgeneration_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DecodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DecodeRequest) ProtoMessage() {} + +func (x *DecodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_textgeneration_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DecodeRequest.ProtoReflect.Descriptor instead. +func (*DecodeRequest) Descriptor() ([]byte, []int) { + return file_textgeneration_proto_rawDescGZIP(), []int{6} +} + +func (x *DecodeRequest) GetBatches() []*CachedBatch { + if x != nil { + return x.Batches + } + return nil +} + +type DecodeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + /// Decodes + Generations []*Generation `protobuf:"bytes,1,rep,name=generations,proto3" json:"generations,omitempty"` + /// Next batch (cached) + Batch *CachedBatch `protobuf:"bytes,2,opt,name=batch,proto3,oneof" json:"batch,omitempty"` +} + +func (x *DecodeResponse) Reset() { + *x = DecodeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_textgeneration_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DecodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DecodeResponse) ProtoMessage() {} + +func (x *DecodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_textgeneration_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DecodeResponse.ProtoReflect.Descriptor instead. +func (*DecodeResponse) Descriptor() ([]byte, []int) { + return file_textgeneration_proto_rawDescGZIP(), []int{7} +} + +func (x *DecodeResponse) GetGenerations() []*Generation { + if x != nil { + return x.Generations + } + return nil +} + +func (x *DecodeResponse) GetBatch() *CachedBatch { + if x != nil { + return x.Batch + } + return nil +} + +var File_textgeneration_proto protoreflect.FileDescriptor + +var file_textgeneration_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x74, 0x65, 0x78, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x22, 0x0a, 0x0c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x26, 0x0a, 0x0a, 0x48, 0x65, + 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x22, 0x53, 0x0a, 0x0d, 0x50, 0x72, 0x65, 0x66, 0x69, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, + 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x70, 0x72, 0x6f, 0x62, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x02, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x70, 0x72, 0x6f, 0x62, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x65, 0x78, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x0b, 0x43, 0x61, 0x63, 0x68, 0x65, + 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, + 0x61, 0x78, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x09, 0x6d, 0x61, 0x78, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x0d, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, + 0x12, 0x29, 0x0a, 0x10, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x32, 0x0a, 0x0d, 0x66, + 0x69, 0x6e, 0x69, 0x73, 0x68, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x52, 0x65, 0x61, 0x73, 0x6f, + 0x6e, 0x52, 0x0c, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, + 0x17, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, + 0x04, 0x73, 0x65, 0x65, 0x64, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, 0x65, 0x65, + 0x64, 0x22, 0xba, 0x02, 0x0a, 0x0a, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x35, 0x0a, 0x0e, 0x70, 0x72, 0x65, 0x66, 0x69, 0x6c, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x50, 0x72, 0x65, 0x66, 0x69, 0x6c, + 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x0d, 0x70, 0x72, 0x65, 0x66, 0x69, 0x6c, 0x6c, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x49, + 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x6c, 0x6f, 0x67, 0x70, 0x72, + 0x6f, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0c, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, + 0x6f, 0x67, 0x70, 0x72, 0x6f, 0x62, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, + 0x74, 0x65, 0x78, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x54, 0x65, 0x78, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, + 0x73, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0e, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x73, 0x53, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x12, + 0x3a, 0x0a, 0x0e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x65, 0x78, + 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x22, 0x37, + 0x0a, 0x0d, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x26, 0x0a, 0x07, 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, + 0x62, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0x72, 0x0a, 0x0e, 0x44, 0x65, 0x63, 0x6f, 0x64, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x0b, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, + 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x05, 0x62, 0x61, 0x74, 0x63, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x64, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x88, 0x01, + 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x2a, 0x66, 0x0a, 0x0c, 0x46, + 0x69, 0x6e, 0x69, 0x73, 0x68, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x14, 0x46, + 0x49, 0x4e, 0x49, 0x53, 0x48, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, + 0x47, 0x54, 0x48, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x49, 0x4e, 0x49, 0x53, 0x48, 0x5f, + 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x45, 0x4f, 0x53, 0x5f, 0x54, 0x4f, 0x4b, 0x45, 0x4e, + 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x46, 0x49, 0x4e, 0x49, 0x53, 0x48, 0x5f, 0x52, 0x45, 0x41, + 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, + 0x45, 0x10, 0x02, 0x32, 0x5e, 0x0a, 0x07, 0x47, 0x72, 0x65, 0x65, 0x74, 0x65, 0x72, 0x12, 0x28, + 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x0d, 0x2e, 0x48, 0x65, 0x6c, + 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x48, 0x65, 0x6c, 0x6c, + 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x29, 0x0a, 0x06, 0x44, 0x65, 0x63, 0x6f, + 0x64, 0x65, 0x12, 0x0e, 0x2e, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x42, 0x43, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x4d, 0x61, 0x78, 0x2d, 0x47, 0x61, 0x62, 0x72, 0x69, 0x65, 0x6c, 0x2d, 0x53, 0x75, + 0x73, 0x6d, 0x61, 0x6e, 0x2f, 0x64, 0x65, 0x6c, 0x70, 0x68, 0x69, 0x2d, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_textgeneration_proto_rawDescOnce sync.Once + file_textgeneration_proto_rawDescData = file_textgeneration_proto_rawDesc +) + +func file_textgeneration_proto_rawDescGZIP() []byte { + file_textgeneration_proto_rawDescOnce.Do(func() { + file_textgeneration_proto_rawDescData = protoimpl.X.CompressGZIP(file_textgeneration_proto_rawDescData) + }) + return file_textgeneration_proto_rawDescData +} + +var file_textgeneration_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_textgeneration_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_textgeneration_proto_goTypes = []interface{}{ + (FinishReason)(0), // 0: FinishReason + (*HelloRequest)(nil), // 1: HelloRequest + (*HelloReply)(nil), // 2: HelloReply + (*PrefillTokens)(nil), // 3: PrefillTokens + (*CachedBatch)(nil), // 4: CachedBatch + (*GeneratedText)(nil), // 5: GeneratedText + (*Generation)(nil), // 6: Generation + (*DecodeRequest)(nil), // 7: DecodeRequest + (*DecodeResponse)(nil), // 8: DecodeResponse +} +var file_textgeneration_proto_depIdxs = []int32{ + 0, // 0: GeneratedText.finish_reason:type_name -> FinishReason + 3, // 1: Generation.prefill_tokens:type_name -> PrefillTokens + 5, // 2: Generation.generated_text:type_name -> GeneratedText + 4, // 3: DecodeRequest.batches:type_name -> CachedBatch + 6, // 4: DecodeResponse.generations:type_name -> Generation + 4, // 5: DecodeResponse.batch:type_name -> CachedBatch + 1, // 6: Greeter.SayHello:input_type -> HelloRequest + 7, // 7: Greeter.Decode:input_type -> DecodeRequest + 2, // 8: Greeter.SayHello:output_type -> HelloReply + 8, // 9: Greeter.Decode:output_type -> DecodeResponse + 8, // [8:10] is the sub-list for method output_type + 6, // [6:8] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_textgeneration_proto_init() } +func file_textgeneration_proto_init() { + if File_textgeneration_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_textgeneration_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HelloRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_textgeneration_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HelloReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_textgeneration_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PrefillTokens); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_textgeneration_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CachedBatch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_textgeneration_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GeneratedText); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_textgeneration_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Generation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_textgeneration_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DecodeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_textgeneration_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DecodeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_textgeneration_proto_msgTypes[4].OneofWrappers = []interface{}{} + file_textgeneration_proto_msgTypes[5].OneofWrappers = []interface{}{} + file_textgeneration_proto_msgTypes[7].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_textgeneration_proto_rawDesc, + NumEnums: 1, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_textgeneration_proto_goTypes, + DependencyIndexes: file_textgeneration_proto_depIdxs, + EnumInfos: file_textgeneration_proto_enumTypes, + MessageInfos: file_textgeneration_proto_msgTypes, + }.Build() + File_textgeneration_proto = out.File + file_textgeneration_proto_rawDesc = nil + file_textgeneration_proto_goTypes = nil + file_textgeneration_proto_depIdxs = nil +} diff --git a/textgeneration/textgeneration.proto b/textgeneration/textgeneration.proto new file mode 100644 index 0000000..dbbf1fa --- /dev/null +++ b/textgeneration/textgeneration.proto @@ -0,0 +1,87 @@ +syntax = "proto3"; + +option go_package = "github.com/Max-Gabriel-Susman/delphi-model-service/textgeneration"; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} + /// Decode token for a list of prefilled batches + rpc Decode (DecodeRequest) returns (DecodeResponse); +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} + +message PrefillTokens { + /// Prefill Token IDs + repeated uint32 ids = 1; + /// Prefill Logprobs + repeated float logprobs = 2; + /// Prefill tokens + repeated string texts = 3; +} + +message CachedBatch { + /// Batch ID + uint64 id = 1; + /// Individual requests ids + repeated uint64 request_ids = 2; + /// Batch size (==len(requests)) + uint32 size = 3; + /// Maximum number of tokens this batch will grow to + uint32 max_tokens = 4; +} + +enum FinishReason { + FINISH_REASON_LENGTH = 0; + FINISH_REASON_EOS_TOKEN = 1; + FINISH_REASON_STOP_SEQUENCE = 2; +} + +message GeneratedText { + /// Output + string text = 1; + /// Number of generated tokens + uint32 generated_tokens = 2; + /// Finish reason + FinishReason finish_reason = 3; + /// Seed + optional uint64 seed = 4; +} + +message Generation { + /// Request ID + uint64 request_id = 1; + /// Prefill tokens (optional) + PrefillTokens prefill_tokens = 2; + /// Token ID + uint32 token_id = 3; + /// Logprob + float token_logprob = 4; + /// Text + string token_text = 5; + /// Is it a special token + bool token_is_special = 6; + /// Complete generated text + optional GeneratedText generated_text = 7; +} + +message DecodeRequest { + /// Cached batches + repeated CachedBatch batches = 1; +} + +message DecodeResponse { + /// Decodes + repeated Generation generations = 1; + /// Next batch (cached) + optional CachedBatch batch = 2; +} \ No newline at end of file diff --git a/textgeneration/textgeneration_grpc.pb.go b/textgeneration/textgeneration_grpc.pb.go new file mode 100644 index 0000000..0e1dcae --- /dev/null +++ b/textgeneration/textgeneration_grpc.pb.go @@ -0,0 +1,145 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v4.24.3 +// source: textgeneration.proto + +package textgeneration + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// GreeterClient is the client API for Greeter service. +// +// 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. +type GreeterClient interface { + // Sends a greeting + SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) + /// Decode token for a list of prefilled batches + Decode(ctx context.Context, in *DecodeRequest, opts ...grpc.CallOption) (*DecodeResponse, error) +} + +type greeterClient struct { + cc grpc.ClientConnInterface +} + +func NewGreeterClient(cc grpc.ClientConnInterface) GreeterClient { + return &greeterClient{cc} +} + +func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { + out := new(HelloReply) + err := c.cc.Invoke(ctx, "/Greeter/SayHello", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *greeterClient) Decode(ctx context.Context, in *DecodeRequest, opts ...grpc.CallOption) (*DecodeResponse, error) { + out := new(DecodeResponse) + err := c.cc.Invoke(ctx, "/Greeter/Decode", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// GreeterServer is the server API for Greeter service. +// All implementations must embed UnimplementedGreeterServer +// for forward compatibility +type GreeterServer interface { + // Sends a greeting + SayHello(context.Context, *HelloRequest) (*HelloReply, error) + /// Decode token for a list of prefilled batches + Decode(context.Context, *DecodeRequest) (*DecodeResponse, error) + mustEmbedUnimplementedGreeterServer() +} + +// UnimplementedGreeterServer must be embedded to have forward compatible implementations. +type UnimplementedGreeterServer struct { +} + +func (UnimplementedGreeterServer) SayHello(context.Context, *HelloRequest) (*HelloReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") +} +func (UnimplementedGreeterServer) Decode(context.Context, *DecodeRequest) (*DecodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Decode not implemented") +} +func (UnimplementedGreeterServer) mustEmbedUnimplementedGreeterServer() {} + +// UnsafeGreeterServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to GreeterServer will +// result in compilation errors. +type UnsafeGreeterServer interface { + mustEmbedUnimplementedGreeterServer() +} + +func RegisterGreeterServer(s grpc.ServiceRegistrar, srv GreeterServer) { + s.RegisterService(&Greeter_ServiceDesc, srv) +} + +func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HelloRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GreeterServer).SayHello(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Greeter/SayHello", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Greeter_Decode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DecodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GreeterServer).Decode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Greeter/Decode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GreeterServer).Decode(ctx, req.(*DecodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Greeter_ServiceDesc is the grpc.ServiceDesc for Greeter service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Greeter_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "Greeter", + HandlerType: (*GreeterServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SayHello", + Handler: _Greeter_SayHello_Handler, + }, + { + MethodName: "Decode", + Handler: _Greeter_Decode_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "textgeneration.proto", +}