From 833a99c546e240071f01c324eb9260aa4336f5c4 Mon Sep 17 00:00:00 2001 From: Abirdcfly Date: Mon, 25 Dec 2023 14:00:57 +0800 Subject: [PATCH] feat: add swagger api doc Signed-off-by: Abirdcfly --- Makefile | 3 + apiserver/config/config.go | 2 + apiserver/docs/docs.go | 541 ++++++++++++++++++ apiserver/docs/swagger.json | 512 +++++++++++++++++ apiserver/docs/swagger.yaml | 357 ++++++++++++ apiserver/pkg/chat/chat.go | 76 +-- apiserver/pkg/chat/chat_type.go | 73 ++- apiserver/service/chat.go | 107 +++- apiserver/service/router.go | 10 +- go.mod | 37 +- go.sum | 83 +-- .../retriever/knowledgebaseretriever.go | 15 +- tests/example-test.sh | 28 +- 13 files changed, 1686 insertions(+), 158 deletions(-) create mode 100644 apiserver/docs/docs.go create mode 100644 apiserver/docs/swagger.json create mode 100644 apiserver/docs/swagger.yaml diff --git a/Makefile b/Makefile index 8c7f3d249..4ee318113 100644 --- a/Makefile +++ b/Makefile @@ -290,6 +290,9 @@ prepare-push: manifests generate fmt vet gql-gen @sed -i '' '$(chart_rule_line_num),$$d' deploy/charts/arcadia/templates/rbac.yaml @cat tmp_role.yaml >> deploy/charts/arcadia/templates/rbac.yaml @rm -f tmp_role.yaml + @echo "install swag" + @go install github.com/swaggo/swag/cmd/swag@latest + @swag init -o apiserver/docs . # Commands for Data-Processing DATA_PROCESSING_IMAGE ?= kubebb/dp-base diff --git a/apiserver/config/config.go b/apiserver/config/config.go index b3b38d2e7..1c446347f 100644 --- a/apiserver/config/config.go +++ b/apiserver/config/config.go @@ -32,6 +32,7 @@ type ServerConfig struct { Host string Port int EnablePlayground bool + EnableSwagger bool EnableOIDC bool PlaygroundEndpointPrefix string @@ -45,6 +46,7 @@ func NewServerFlags() ServerConfig { flag.StringVar(&s.Host, "host", "", "bind to the host, default is 0.0.0.0") flag.IntVar(&s.Port, "port", 8081, "service listening port") flag.BoolVar(&s.EnablePlayground, "enable-playground", false, "enable the graphql playground") + flag.BoolVar(&s.EnableSwagger, "enable-swagger", true, "enable the swagger doc") flag.BoolVar(&s.EnableOIDC, "enable-oidc", false, "enable oidc authorization") flag.StringVar(&s.PlaygroundEndpointPrefix, "playground-endpoint-prefix", "", "this parameter should also be configured when the service is forwarded via ingress and a path prefix is configured to avoid not finding the service, such as /apis") flag.StringVar(&s.IssuerURL, "issuer-url", "", "oidc issuer url(required when enable odic)") diff --git a/apiserver/docs/docs.go b/apiserver/docs/docs.go new file mode 100644 index 000000000..7790b5583 --- /dev/null +++ b/apiserver/docs/docs.go @@ -0,0 +1,541 @@ +// Package docs Code generated by swaggo/swag. DO NOT EDIT +package docs + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "contact": {}, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/": { + "post": { + "description": "chat with application", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "application" + ], + "summary": "chat with application", + "parameters": [ + { + "type": "boolean", + "description": "Should the chat request be treated as debugging?", + "name": "debug", + "in": "query" + }, + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/chat.ChatReqBody" + } + } + ], + "responses": { + "200": { + "description": "blocking mode, will return all field; streaming mode, only conversation_id, message and created_at will be returned", + "schema": { + "$ref": "#/definitions/chat.ChatRespBody" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + } + } + } + }, + "/conversations": { + "post": { + "description": "list all conversations", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "application" + ], + "summary": "list all conversations", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/chat.APPMetadata" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/chat.Conversation" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + } + } + } + }, + "/conversations/:conversationID": { + "delete": { + "description": "delete one conversation", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "application" + ], + "summary": "delete one conversation", + "parameters": [ + { + "type": "string", + "description": "conversationID", + "name": "conversationID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/chat.SimpleResp" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + } + } + } + }, + "/messages": { + "post": { + "description": "get all messages history for one conversation", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "application" + ], + "summary": "get all messages history for one conversation", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/chat.ConversationReqBody" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/chat.Conversation" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + } + } + } + }, + "/messages/:messageID/references": { + "post": { + "description": "get one message's references", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "application" + ], + "summary": "get one message references", + "parameters": [ + { + "type": "string", + "description": "messageID", + "name": "messageID", + "in": "path", + "required": true + }, + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/chat.MessageReqBody" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/retriever.Reference" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + } + } + } + } + }, + "definitions": { + "chat.APPMetadata": { + "type": "object", + "required": [ + "app_name", + "app_namespace" + ], + "properties": { + "app_name": { + "description": "AppName, the name of the application", + "type": "string", + "example": "chat-with-llm" + }, + "app_namespace": { + "description": "AppNamespace, the namespace of the application", + "type": "string", + "example": "arcadia" + } + } + }, + "chat.ChatReqBody": { + "type": "object", + "required": [ + "app_name", + "app_namespace", + "query", + "response_mode" + ], + "properties": { + "app_name": { + "description": "AppName, the name of the application", + "type": "string", + "example": "chat-with-llm" + }, + "app_namespace": { + "description": "AppNamespace, the namespace of the application", + "type": "string", + "example": "arcadia" + }, + "conversation_id": { + "description": "ConversationID, if it is empty, a new conversation will be created", + "type": "string", + "example": "5a41f3ca-763b-41ec-91c3-4bbbb00736d0" + }, + "query": { + "description": "Query user query string", + "type": "string", + "example": "旷工最小计算单位为多少天?" + }, + "response_mode": { + "description": "ResponseMode:\n* Blocking - means the response is returned in a blocking manner\n* Streaming - means the response will use Server-Sent Events", + "allOf": [ + { + "$ref": "#/definitions/chat.ResponseMode" + } + ], + "example": "blocking" + } + } + }, + "chat.ChatRespBody": { + "type": "object", + "properties": { + "conversation_id": { + "type": "string", + "example": "5a41f3ca-763b-41ec-91c3-4bbbb00736d0" + }, + "created_at": { + "description": "CreatedAt is the time when the message is created", + "type": "string", + "example": "2023-12-21T10:21:06.389359092+08:00" + }, + "message": { + "description": "Message is what AI say", + "type": "string", + "example": "旷工最小计算单位为0.5天。" + }, + "message_id": { + "type": "string", + "example": "4f3546dd-5404-4bf8-a3bc-4fa3f9a7ba24" + }, + "references": { + "description": "References is the list of references", + "type": "array", + "items": { + "$ref": "#/definitions/retriever.Reference" + } + } + } + }, + "chat.Conversation": { + "type": "object", + "properties": { + "app_name": { + "type": "string", + "example": "chat-with-llm" + }, + "app_namespace": { + "type": "string", + "example": "arcadia" + }, + "id": { + "type": "string", + "example": "5a41f3ca-763b-41ec-91c3-4bbbb00736d0" + }, + "messages": { + "type": "array", + "items": { + "$ref": "#/definitions/chat.Message" + } + }, + "started_at": { + "type": "string", + "example": "2023-12-21T10:21:06.389359092+08:00" + }, + "updated_at": { + "type": "string", + "example": "2023-12-22T10:21:06.389359092+08:00" + } + } + }, + "chat.ConversationReqBody": { + "type": "object", + "required": [ + "app_name", + "app_namespace" + ], + "properties": { + "app_name": { + "description": "AppName, the name of the application", + "type": "string", + "example": "chat-with-llm" + }, + "app_namespace": { + "description": "AppNamespace, the namespace of the application", + "type": "string", + "example": "arcadia" + }, + "conversation_id": { + "description": "ConversationID, if it is empty, a new conversation will be created", + "type": "string", + "example": "5a41f3ca-763b-41ec-91c3-4bbbb00736d0" + } + } + }, + "chat.ErrorResp": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "conversation is not found" + } + } + }, + "chat.Message": { + "type": "object", + "properties": { + "answer": { + "type": "string", + "example": "旷工最小计算单位为0.5天。" + }, + "id": { + "type": "string", + "example": "4f3546dd-5404-4bf8-a3bc-4fa3f9a7ba24" + }, + "query": { + "type": "string", + "example": "旷工最小计算单位为多少天?" + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/retriever.Reference" + } + } + } + }, + "chat.MessageReqBody": { + "type": "object", + "required": [ + "app_name", + "app_namespace" + ], + "properties": { + "app_name": { + "description": "AppName, the name of the application", + "type": "string", + "example": "chat-with-llm" + }, + "app_namespace": { + "description": "AppNamespace, the namespace of the application", + "type": "string", + "example": "arcadia" + }, + "conversation_id": { + "description": "ConversationID, if it is empty, a new conversation will be created", + "type": "string", + "example": "5a41f3ca-763b-41ec-91c3-4bbbb00736d0" + }, + "message_id": { + "description": "MessageID, single message id", + "type": "string", + "example": "4f3546dd-5404-4bf8-a3bc-4fa3f9a7ba24" + } + } + }, + "chat.ResponseMode": { + "type": "string", + "enum": [ + "blocking", + "streaming" + ], + "x-enum-varnames": [ + "Blocking", + "Streaming" + ] + }, + "chat.SimpleResp": { + "type": "object", + "properties": { + "message": { + "type": "string", + "example": "ok" + } + } + }, + "retriever.Reference": { + "type": "object", + "properties": { + "answer": { + "description": "Answer row", + "type": "string", + "example": "旷工最小计算单位为 0.5 天。" + }, + "file_path": { + "description": "file fullpath", + "type": "string", + "example": "dataset/dataset-playground/v1/qa.csv" + }, + "line_number": { + "description": "line number in the file", + "type": "integer", + "example": 7 + }, + "question": { + "description": "Question row", + "type": "string", + "example": "q: 旷工最小计算单位为多少天?" + }, + "score": { + "description": "vector search score", + "type": "number", + "example": 0.34 + } + } + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "", + Host: "", + BasePath: "", + Schemes: []string{}, + Title: "", + Description: "", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/apiserver/docs/swagger.json b/apiserver/docs/swagger.json new file mode 100644 index 000000000..3a4d96ddb --- /dev/null +++ b/apiserver/docs/swagger.json @@ -0,0 +1,512 @@ +{ + "swagger": "2.0", + "info": { + "contact": {} + }, + "paths": { + "/": { + "post": { + "description": "chat with application", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "application" + ], + "summary": "chat with application", + "parameters": [ + { + "type": "boolean", + "description": "Should the chat request be treated as debugging?", + "name": "debug", + "in": "query" + }, + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/chat.ChatReqBody" + } + } + ], + "responses": { + "200": { + "description": "blocking mode, will return all field; streaming mode, only conversation_id, message and created_at will be returned", + "schema": { + "$ref": "#/definitions/chat.ChatRespBody" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + } + } + } + }, + "/conversations": { + "post": { + "description": "list all conversations", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "application" + ], + "summary": "list all conversations", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/chat.APPMetadata" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/chat.Conversation" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + } + } + } + }, + "/conversations/:conversationID": { + "delete": { + "description": "delete one conversation", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "application" + ], + "summary": "delete one conversation", + "parameters": [ + { + "type": "string", + "description": "conversationID", + "name": "conversationID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/chat.SimpleResp" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + } + } + } + }, + "/messages": { + "post": { + "description": "get all messages history for one conversation", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "application" + ], + "summary": "get all messages history for one conversation", + "parameters": [ + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/chat.ConversationReqBody" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/chat.Conversation" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + } + } + } + }, + "/messages/:messageID/references": { + "post": { + "description": "get one message's references", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "application" + ], + "summary": "get one message references", + "parameters": [ + { + "type": "string", + "description": "messageID", + "name": "messageID", + "in": "path", + "required": true + }, + { + "description": "query params", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/chat.MessageReqBody" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/retriever.Reference" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/chat.ErrorResp" + } + } + } + } + } + }, + "definitions": { + "chat.APPMetadata": { + "type": "object", + "required": [ + "app_name", + "app_namespace" + ], + "properties": { + "app_name": { + "description": "AppName, the name of the application", + "type": "string", + "example": "chat-with-llm" + }, + "app_namespace": { + "description": "AppNamespace, the namespace of the application", + "type": "string", + "example": "arcadia" + } + } + }, + "chat.ChatReqBody": { + "type": "object", + "required": [ + "app_name", + "app_namespace", + "query", + "response_mode" + ], + "properties": { + "app_name": { + "description": "AppName, the name of the application", + "type": "string", + "example": "chat-with-llm" + }, + "app_namespace": { + "description": "AppNamespace, the namespace of the application", + "type": "string", + "example": "arcadia" + }, + "conversation_id": { + "description": "ConversationID, if it is empty, a new conversation will be created", + "type": "string", + "example": "5a41f3ca-763b-41ec-91c3-4bbbb00736d0" + }, + "query": { + "description": "Query user query string", + "type": "string", + "example": "旷工最小计算单位为多少天?" + }, + "response_mode": { + "description": "ResponseMode:\n* Blocking - means the response is returned in a blocking manner\n* Streaming - means the response will use Server-Sent Events", + "allOf": [ + { + "$ref": "#/definitions/chat.ResponseMode" + } + ], + "example": "blocking" + } + } + }, + "chat.ChatRespBody": { + "type": "object", + "properties": { + "conversation_id": { + "type": "string", + "example": "5a41f3ca-763b-41ec-91c3-4bbbb00736d0" + }, + "created_at": { + "description": "CreatedAt is the time when the message is created", + "type": "string", + "example": "2023-12-21T10:21:06.389359092+08:00" + }, + "message": { + "description": "Message is what AI say", + "type": "string", + "example": "旷工最小计算单位为0.5天。" + }, + "message_id": { + "type": "string", + "example": "4f3546dd-5404-4bf8-a3bc-4fa3f9a7ba24" + }, + "references": { + "description": "References is the list of references", + "type": "array", + "items": { + "$ref": "#/definitions/retriever.Reference" + } + } + } + }, + "chat.Conversation": { + "type": "object", + "properties": { + "app_name": { + "type": "string", + "example": "chat-with-llm" + }, + "app_namespace": { + "type": "string", + "example": "arcadia" + }, + "id": { + "type": "string", + "example": "5a41f3ca-763b-41ec-91c3-4bbbb00736d0" + }, + "messages": { + "type": "array", + "items": { + "$ref": "#/definitions/chat.Message" + } + }, + "started_at": { + "type": "string", + "example": "2023-12-21T10:21:06.389359092+08:00" + }, + "updated_at": { + "type": "string", + "example": "2023-12-22T10:21:06.389359092+08:00" + } + } + }, + "chat.ConversationReqBody": { + "type": "object", + "required": [ + "app_name", + "app_namespace" + ], + "properties": { + "app_name": { + "description": "AppName, the name of the application", + "type": "string", + "example": "chat-with-llm" + }, + "app_namespace": { + "description": "AppNamespace, the namespace of the application", + "type": "string", + "example": "arcadia" + }, + "conversation_id": { + "description": "ConversationID, if it is empty, a new conversation will be created", + "type": "string", + "example": "5a41f3ca-763b-41ec-91c3-4bbbb00736d0" + } + } + }, + "chat.ErrorResp": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "conversation is not found" + } + } + }, + "chat.Message": { + "type": "object", + "properties": { + "answer": { + "type": "string", + "example": "旷工最小计算单位为0.5天。" + }, + "id": { + "type": "string", + "example": "4f3546dd-5404-4bf8-a3bc-4fa3f9a7ba24" + }, + "query": { + "type": "string", + "example": "旷工最小计算单位为多少天?" + }, + "references": { + "type": "array", + "items": { + "$ref": "#/definitions/retriever.Reference" + } + } + } + }, + "chat.MessageReqBody": { + "type": "object", + "required": [ + "app_name", + "app_namespace" + ], + "properties": { + "app_name": { + "description": "AppName, the name of the application", + "type": "string", + "example": "chat-with-llm" + }, + "app_namespace": { + "description": "AppNamespace, the namespace of the application", + "type": "string", + "example": "arcadia" + }, + "conversation_id": { + "description": "ConversationID, if it is empty, a new conversation will be created", + "type": "string", + "example": "5a41f3ca-763b-41ec-91c3-4bbbb00736d0" + }, + "message_id": { + "description": "MessageID, single message id", + "type": "string", + "example": "4f3546dd-5404-4bf8-a3bc-4fa3f9a7ba24" + } + } + }, + "chat.ResponseMode": { + "type": "string", + "enum": [ + "blocking", + "streaming" + ], + "x-enum-varnames": [ + "Blocking", + "Streaming" + ] + }, + "chat.SimpleResp": { + "type": "object", + "properties": { + "message": { + "type": "string", + "example": "ok" + } + } + }, + "retriever.Reference": { + "type": "object", + "properties": { + "answer": { + "description": "Answer row", + "type": "string", + "example": "旷工最小计算单位为 0.5 天。" + }, + "file_path": { + "description": "file fullpath", + "type": "string", + "example": "dataset/dataset-playground/v1/qa.csv" + }, + "line_number": { + "description": "line number in the file", + "type": "integer", + "example": 7 + }, + "question": { + "description": "Question row", + "type": "string", + "example": "q: 旷工最小计算单位为多少天?" + }, + "score": { + "description": "vector search score", + "type": "number", + "example": 0.34 + } + } + } + } +} \ No newline at end of file diff --git a/apiserver/docs/swagger.yaml b/apiserver/docs/swagger.yaml new file mode 100644 index 000000000..4a8335b93 --- /dev/null +++ b/apiserver/docs/swagger.yaml @@ -0,0 +1,357 @@ +definitions: + chat.APPMetadata: + properties: + app_name: + description: AppName, the name of the application + example: chat-with-llm + type: string + app_namespace: + description: AppNamespace, the namespace of the application + example: arcadia + type: string + required: + - app_name + - app_namespace + type: object + chat.ChatReqBody: + properties: + app_name: + description: AppName, the name of the application + example: chat-with-llm + type: string + app_namespace: + description: AppNamespace, the namespace of the application + example: arcadia + type: string + conversation_id: + description: ConversationID, if it is empty, a new conversation will be created + example: 5a41f3ca-763b-41ec-91c3-4bbbb00736d0 + type: string + query: + description: Query user query string + example: 旷工最小计算单位为多少天? + type: string + response_mode: + allOf: + - $ref: '#/definitions/chat.ResponseMode' + description: |- + ResponseMode: + * Blocking - means the response is returned in a blocking manner + * Streaming - means the response will use Server-Sent Events + example: blocking + required: + - app_name + - app_namespace + - query + - response_mode + type: object + chat.ChatRespBody: + properties: + conversation_id: + example: 5a41f3ca-763b-41ec-91c3-4bbbb00736d0 + type: string + created_at: + description: CreatedAt is the time when the message is created + example: "2023-12-21T10:21:06.389359092+08:00" + type: string + message: + description: Message is what AI say + example: 旷工最小计算单位为0.5天。 + type: string + message_id: + example: 4f3546dd-5404-4bf8-a3bc-4fa3f9a7ba24 + type: string + references: + description: References is the list of references + items: + $ref: '#/definitions/retriever.Reference' + type: array + type: object + chat.Conversation: + properties: + app_name: + example: chat-with-llm + type: string + app_namespace: + example: arcadia + type: string + id: + example: 5a41f3ca-763b-41ec-91c3-4bbbb00736d0 + type: string + messages: + items: + $ref: '#/definitions/chat.Message' + type: array + started_at: + example: "2023-12-21T10:21:06.389359092+08:00" + type: string + updated_at: + example: "2023-12-22T10:21:06.389359092+08:00" + type: string + type: object + chat.ConversationReqBody: + properties: + app_name: + description: AppName, the name of the application + example: chat-with-llm + type: string + app_namespace: + description: AppNamespace, the namespace of the application + example: arcadia + type: string + conversation_id: + description: ConversationID, if it is empty, a new conversation will be created + example: 5a41f3ca-763b-41ec-91c3-4bbbb00736d0 + type: string + required: + - app_name + - app_namespace + type: object + chat.ErrorResp: + properties: + error: + example: conversation is not found + type: string + type: object + chat.Message: + properties: + answer: + example: 旷工最小计算单位为0.5天。 + type: string + id: + example: 4f3546dd-5404-4bf8-a3bc-4fa3f9a7ba24 + type: string + query: + example: 旷工最小计算单位为多少天? + type: string + references: + items: + $ref: '#/definitions/retriever.Reference' + type: array + type: object + chat.MessageReqBody: + properties: + app_name: + description: AppName, the name of the application + example: chat-with-llm + type: string + app_namespace: + description: AppNamespace, the namespace of the application + example: arcadia + type: string + conversation_id: + description: ConversationID, if it is empty, a new conversation will be created + example: 5a41f3ca-763b-41ec-91c3-4bbbb00736d0 + type: string + message_id: + description: MessageID, single message id + example: 4f3546dd-5404-4bf8-a3bc-4fa3f9a7ba24 + type: string + required: + - app_name + - app_namespace + type: object + chat.ResponseMode: + enum: + - blocking + - streaming + type: string + x-enum-varnames: + - Blocking + - Streaming + chat.SimpleResp: + properties: + message: + example: ok + type: string + type: object + retriever.Reference: + properties: + answer: + description: Answer row + example: 旷工最小计算单位为 0.5 天。 + type: string + file_path: + description: file fullpath + example: dataset/dataset-playground/v1/qa.csv + type: string + line_number: + description: line number in the file + example: 7 + type: integer + question: + description: Question row + example: 'q: 旷工最小计算单位为多少天?' + type: string + score: + description: vector search score + example: 0.34 + type: number + type: object +info: + contact: {} +paths: + /: + post: + consumes: + - application/json + description: chat with application + parameters: + - description: Should the chat request be treated as debugging? + in: query + name: debug + type: boolean + - description: query params + in: body + name: request + required: true + schema: + $ref: '#/definitions/chat.ChatReqBody' + produces: + - application/json + responses: + "200": + description: blocking mode, will return all field; streaming mode, only + conversation_id, message and created_at will be returned + schema: + $ref: '#/definitions/chat.ChatRespBody' + "400": + description: Bad Request + schema: + $ref: '#/definitions/chat.ErrorResp' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/chat.ErrorResp' + summary: chat with application + tags: + - application + /conversations: + post: + consumes: + - application/json + description: list all conversations + parameters: + - description: query params + in: body + name: request + required: true + schema: + $ref: '#/definitions/chat.APPMetadata' + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/chat.Conversation' + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/chat.ErrorResp' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/chat.ErrorResp' + summary: list all conversations + tags: + - application + /conversations/:conversationID: + delete: + consumes: + - application/json + description: delete one conversation + parameters: + - description: conversationID + in: path + name: conversationID + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/chat.SimpleResp' + "400": + description: Bad Request + schema: + $ref: '#/definitions/chat.ErrorResp' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/chat.ErrorResp' + summary: delete one conversation + tags: + - application + /messages: + post: + consumes: + - application/json + description: get all messages history for one conversation + parameters: + - description: query params + in: body + name: request + required: true + schema: + $ref: '#/definitions/chat.ConversationReqBody' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/chat.Conversation' + "400": + description: Bad Request + schema: + $ref: '#/definitions/chat.ErrorResp' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/chat.ErrorResp' + summary: get all messages history for one conversation + tags: + - application + /messages/:messageID/references: + post: + consumes: + - application/json + description: get one message's references + parameters: + - description: messageID + in: path + name: messageID + required: true + type: string + - description: query params + in: body + name: request + required: true + schema: + $ref: '#/definitions/chat.MessageReqBody' + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/retriever.Reference' + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/chat.ErrorResp' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/chat.ErrorResp' + summary: get one message references + tags: + - application +swagger: "2.0" diff --git a/apiserver/pkg/chat/chat.go b/apiserver/pkg/chat/chat.go index a43a4d780..69a614c5a 100644 --- a/apiserver/pkg/chat/chat.go +++ b/apiserver/pkg/chat/chat.go @@ -38,8 +38,8 @@ import ( ) var ( - mu sync.Mutex - Conversions = map[string]Conversion{} + mu sync.Mutex + Conversations = map[string]Conversation{} ) func AppRun(ctx context.Context, req ChatReqBody, respStream chan string) (*ChatRespBody, error) { @@ -61,25 +61,25 @@ func AppRun(ctx context.Context, req ChatReqBody, respStream chan string) (*Chat if !app.Status.IsReady() { return nil, errors.New("application is not ready") } - var conversion Conversion + var conversation Conversation currentUser, _ := ctx.Value(auth.UserNameContextKey).(string) - if req.ConversionID != "" { + if req.ConversationID != "" { var ok bool - conversion, ok = Conversions[req.ConversionID] + conversation, ok = Conversations[req.ConversationID] if !ok { - return nil, errors.New("conversion is not found") + return nil, errors.New("conversation is not found") } - if currentUser != "" && currentUser != conversion.User { - return nil, errors.New("conversion id not match with user") + if currentUser != "" && currentUser != conversation.User { + return nil, errors.New("conversation id not match with user") } - if conversion.AppName != req.APPName || conversion.AppNamespce != req.AppNamespace { - return nil, errors.New("conversion id not match with app info") + if conversation.AppName != req.APPName || conversation.AppNamespce != req.AppNamespace { + return nil, errors.New("conversation id not match with app info") } - if conversion.Debug != req.Debug { - return nil, errors.New("conversion id not match with debug") + if conversation.Debug != req.Debug { + return nil, errors.New("conversation id not match with debug") } } else { - conversion = Conversion{ + conversation = Conversation{ ID: string(uuid.NewUUID()), AppName: req.APPName, AppNamespce: req.AppNamespace, @@ -92,7 +92,7 @@ func AppRun(ctx context.Context, req ChatReqBody, respStream chan string) (*Chat } } messageID := string(uuid.NewUUID()) - conversion.Messages = append(conversion.Messages, Message{ + conversation.Messages = append(conversation.Messages, Message{ ID: messageID, Query: req.Query, Answer: "", @@ -103,31 +103,31 @@ func AppRun(ctx context.Context, req ChatReqBody, respStream chan string) (*Chat return nil, err } klog.Infoln("begin to run application", obj.GetName()) - out, err := appRun.Run(ctx, c, respStream, application.Input{Question: req.Query, NeedStream: req.ResponseMode == Streaming, History: conversion.History}) + out, err := appRun.Run(ctx, c, respStream, application.Input{Question: req.Query, NeedStream: req.ResponseMode == Streaming, History: conversation.History}) if err != nil { return nil, err } - conversion.UpdatedAt = time.Now() - conversion.Messages[len(conversion.Messages)-1].Answer = out.Answer - conversion.Messages[len(conversion.Messages)-1].References = out.References + conversation.UpdatedAt = time.Now() + conversation.Messages[len(conversation.Messages)-1].Answer = out.Answer + conversation.Messages[len(conversation.Messages)-1].References = out.References mu.Lock() - Conversions[conversion.ID] = conversion + Conversations[conversation.ID] = conversation mu.Unlock() return &ChatRespBody{ - ConversionID: conversion.ID, - MessageID: messageID, - Message: out.Answer, - CreatedAt: time.Now(), - References: out.References, + ConversationID: conversation.ID, + MessageID: messageID, + Message: out.Answer, + CreatedAt: time.Now(), + References: out.References, }, nil } -func ListConversations(ctx context.Context, req APPMetadata) ([]Conversion, error) { - conversations := make([]Conversion, 0) +func ListConversations(ctx context.Context, req APPMetadata) ([]Conversation, error) { + conversations := make([]Conversation, 0) currentUser, _ := ctx.Value(auth.UserNameContextKey).(string) mu.Lock() - for _, c := range Conversions { + for _, c := range Conversations { if !c.Debug && c.AppName == req.APPName && c.AppNamespce == req.AppNamespace && (currentUser == "" || currentUser == c.User) { conversations = append(conversations, c) } @@ -136,37 +136,37 @@ func ListConversations(ctx context.Context, req APPMetadata) ([]Conversion, erro return conversations, nil } -func DeleteConversation(ctx context.Context, conversionID string) error { +func DeleteConversation(ctx context.Context, conversationID string) error { currentUser, _ := ctx.Value(auth.UserNameContextKey).(string) mu.Lock() defer mu.Unlock() - c, ok := Conversions[conversionID] + c, ok := Conversations[conversationID] if ok && (currentUser == "" || currentUser == c.User) { - delete(Conversions, c.ID) + delete(Conversations, c.ID) return nil } else { - return errors.New("conversion is not found") + return errors.New("conversation is not found") } } -func ListMessages(ctx context.Context, req ConversionReqBody) (Conversion, error) { +func ListMessages(ctx context.Context, req ConversationReqBody) (Conversation, error) { currentUser, _ := ctx.Value(auth.UserNameContextKey).(string) mu.Lock() defer mu.Unlock() - for _, c := range Conversions { - if c.AppName == req.APPName && c.AppNamespce == req.AppNamespace && req.ConversionID == c.ID && (currentUser == "" || currentUser == c.User) { + for _, c := range Conversations { + if c.AppName == req.APPName && c.AppNamespce == req.AppNamespace && req.ConversationID == c.ID && (currentUser == "" || currentUser == c.User) { return c, nil } } - return Conversion{}, errors.New("conversion is not found") + return Conversation{}, errors.New("conversation is not found") } func GetMessageReferences(ctx context.Context, req MessageReqBody) ([]retriever.Reference, error) { currentUser, _ := ctx.Value(auth.UserNameContextKey).(string) mu.Lock() defer mu.Unlock() - for _, c := range Conversions { - if c.AppName == req.APPName && c.AppNamespce == req.AppNamespace && c.ID == req.ConversionID && (currentUser == "" || currentUser == c.User) { + for _, c := range Conversations { + if c.AppName == req.APPName && c.AppNamespce == req.AppNamespace && c.ID == req.ConversationID && (currentUser == "" || currentUser == c.User) { for _, m := range c.Messages { if m.ID == req.MessageID { return m.References, nil @@ -174,7 +174,7 @@ func GetMessageReferences(ctx context.Context, req MessageReqBody) ([]retriever. } } } - return nil, errors.New("conversion or message is not found") + return nil, errors.New("conversation or message is not found") } // todo Reuse the flow without having to rebuild req same, not finish, Flow doesn't start with/contain nodes that depend on incomingInput.question diff --git a/apiserver/pkg/chat/chat_type.go b/apiserver/pkg/chat/chat_type.go index 2a45bfd34..67f970bb0 100644 --- a/apiserver/pkg/chat/chat_type.go +++ b/apiserver/pkg/chat/chat_type.go @@ -27,47 +27,60 @@ import ( type ResponseMode string const ( - Blocking ResponseMode = "blocking" + // Blocking means the response is returned in a blocking manner + Blocking ResponseMode = "blocking" + // Streaming means the response will use Server-Sent Events Streaming ResponseMode = "streaming" // todo isFlowValidForStream only some node(llm chain) support streaming ) type APPMetadata struct { - APPName string `json:"app_name" binding:"required"` - AppNamespace string `json:"app_namespace" binding:"required"` + // AppName, the name of the application + APPName string `json:"app_name" binding:"required" example:"chat-with-llm"` + // AppNamespace, the namespace of the application + AppNamespace string `json:"app_namespace" binding:"required" example:"arcadia"` } -type ConversionReqBody struct { - APPMetadata `json:",inline"` - ConversionID string `json:"conversion_id"` +type ConversationReqBody struct { + APPMetadata `json:",inline"` + // ConversationID, if it is empty, a new conversation will be created + ConversationID string `json:"conversation_id" example:"5a41f3ca-763b-41ec-91c3-4bbbb00736d0"` } type MessageReqBody struct { - ConversionReqBody `json:",inline"` - MessageID string `json:"message_id"` + ConversationReqBody `json:",inline"` + // MessageID, single message id + MessageID string `json:"message_id" example:"4f3546dd-5404-4bf8-a3bc-4fa3f9a7ba24"` } type ChatReqBody struct { - Query string `json:"query" binding:"required"` - ResponseMode ResponseMode `json:"response_mode" binding:"required"` - ConversionReqBody `json:",inline"` - Debug bool `json:"-"` + // Query user query string + Query string `json:"query" binding:"required" example:"旷工最小计算单位为多少天?"` + // ResponseMode: + // * Blocking - means the response is returned in a blocking manner + // * Streaming - means the response will use Server-Sent Events + ResponseMode ResponseMode `json:"response_mode" binding:"required" example:"blocking"` + ConversationReqBody `json:",inline"` + Debug bool `json:"-"` } type ChatRespBody struct { - ConversionID string `json:"conversion_id"` - MessageID string `json:"message_id"` - Message string `json:"message"` - CreatedAt time.Time `json:"created_at"` - References []retriever.Reference `json:"references,omitempty"` + ConversationID string `json:"conversation_id" example:"5a41f3ca-763b-41ec-91c3-4bbbb00736d0"` + MessageID string `json:"message_id" example:"4f3546dd-5404-4bf8-a3bc-4fa3f9a7ba24"` + // Message is what AI say + Message string `json:"message" example:"旷工最小计算单位为0.5天。"` + // CreatedAt is the time when the message is created + CreatedAt time.Time `json:"created_at" example:"2023-12-21T10:21:06.389359092+08:00"` + // References is the list of references + References []retriever.Reference `json:"references,omitempty"` } -type Conversion struct { - ID string `json:"id"` - AppName string `json:"app_name"` - AppNamespce string `json:"app_namespace"` - StartedAt time.Time `json:"started_at"` - UpdatedAt time.Time `json:"updated_at"` +type Conversation struct { + ID string `json:"id" example:"5a41f3ca-763b-41ec-91c3-4bbbb00736d0"` + AppName string `json:"app_name" example:"chat-with-llm"` + AppNamespce string `json:"app_namespace" example:"arcadia"` + StartedAt time.Time `json:"started_at" example:"2023-12-21T10:21:06.389359092+08:00"` + UpdatedAt time.Time `json:"updated_at" example:"2023-12-22T10:21:06.389359092+08:00"` Messages []Message `json:"messages"` History *memory.ChatMessageHistory `json:"-"` User string `json:"-"` @@ -75,8 +88,16 @@ type Conversion struct { } type Message struct { - ID string `json:"id"` - Query string `json:"query"` - Answer string `json:"answer"` + ID string `json:"id" example:"4f3546dd-5404-4bf8-a3bc-4fa3f9a7ba24"` + Query string `json:"query" example:"旷工最小计算单位为多少天?"` + Answer string `json:"answer" example:"旷工最小计算单位为0.5天。"` References []retriever.Reference `json:"references,omitempty"` } + +type ErrorResp struct { + Err string `json:"error" example:"conversation is not found"` +} + +type SimpleResp struct { + Message string `json:"message" example:"ok"` +} diff --git a/apiserver/service/chat.go b/apiserver/service/chat.go index ffa983bf4..c19730b58 100644 --- a/apiserver/service/chat.go +++ b/apiserver/service/chat.go @@ -31,11 +31,25 @@ import ( "github.com/kubeagi/arcadia/apiserver/pkg/oidc" ) +// @BasePath /chat + +// @Summary chat with application +// @Schemes +// @Description chat with application +// @Tags application +// @Accept json +// @Produce json +// @Param debug query bool false "Should the chat request be treated as debugging?" +// @Param request body chat.ChatReqBody true "query params" +// @Success 200 {object} chat.ChatRespBody "blocking mode, will return all field; streaming mode, only conversation_id, message and created_at will be returned" +// @Failure 400 {object} chat.ErrorResp +// @Failure 500 {object} chat.ErrorResp +// @Router / [post] func chatHandler() gin.HandlerFunc { return func(c *gin.Context) { req := chat.ChatReqBody{} if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: err.Error()}) return } req.Debug = c.Query("debug") == "true" @@ -84,13 +98,13 @@ func chatHandler() gin.HandlerFunc { c.Writer.Header().Set("Cache-Control", "no-cache") c.Writer.Header().Set("Connection", "keep-alive") c.Writer.Header().Set("Transfer-Encoding", "chunked") - klog.Infoln("start to receive message") + klog.Infoln("start to receive messages...") clientDisconnected := c.Stream(func(w io.Writer) bool { if msg, ok := <-respStream; ok { c.SSEvent("", chat.ChatRespBody{ - ConversionID: req.ConversionID, - Message: msg, - CreatedAt: time.Now(), + ConversationID: req.ConversationID, + Message: msg, + CreatedAt: time.Now(), }) hasData = true buf.WriteString(msg) @@ -101,12 +115,12 @@ func chatHandler() gin.HandlerFunc { if clientDisconnected { klog.Infoln("chatHandler: client is disconnected") } - klog.Infoln("end to receive message") + klog.Infoln("end to receive messages.") } else { // handle chat blocking mode response, err = chat.AppRun(c, req, nil) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, chat.ErrorResp{Err: err.Error()}) klog.Infof("error resp: %v", err) return } @@ -115,16 +129,27 @@ func chatHandler() gin.HandlerFunc { } } +// @Summary list all conversations +// @Schemes +// @Description list all conversations +// @Tags application +// @Accept json +// @Produce json +// @Param request body chat.APPMetadata true "query params" +// @Success 200 {object} []chat.Conversation +// @Failure 400 {object} chat.ErrorResp +// @Failure 500 {object} chat.ErrorResp +// @Router /conversations [post] func listConversationHandler() gin.HandlerFunc { return func(c *gin.Context) { req := chat.APPMetadata{} if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: err.Error()}) return } resp, err := chat.ListConversations(c, req) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, chat.ErrorResp{Err: err.Error()}) klog.Infof("error resp: %v", err) return } @@ -132,33 +157,55 @@ func listConversationHandler() gin.HandlerFunc { } } +// @Summary delete one conversation +// @Schemes +// @Description delete one conversation +// @Tags application +// @Accept json +// @Produce json +// @Param conversationID path string true "conversationID" +// @Success 200 {object} chat.SimpleResp +// @Failure 400 {object} chat.ErrorResp +// @Failure 500 {object} chat.ErrorResp +// @Router /conversations/:conversationID [delete] func deleteConversationHandler() gin.HandlerFunc { return func(c *gin.Context) { - conversionID := c.Param("conversionID") - if conversionID == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "conversionID is required"}) + conversationID := c.Param("conversationID") + if conversationID == "" { + c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: "conversationID is required"}) return } - err := chat.DeleteConversation(c, conversionID) + err := chat.DeleteConversation(c, conversationID) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, chat.ErrorResp{Err: err.Error()}) klog.Infof("error resp: %v", err) return } - c.JSON(http.StatusOK, gin.H{"message": "ok"}) + c.JSON(http.StatusOK, chat.SimpleResp{Message: "ok"}) } } +// @Summary get all messages history for one conversation +// @Schemes +// @Description get all messages history for one conversation +// @Tags application +// @Accept json +// @Produce json +// @Param request body chat.ConversationReqBody true "query params" +// @Success 200 {object} chat.Conversation +// @Failure 400 {object} chat.ErrorResp +// @Failure 500 {object} chat.ErrorResp +// @Router /messages [post] func historyHandler() gin.HandlerFunc { return func(c *gin.Context) { - req := chat.ConversionReqBody{} + req := chat.ConversationReqBody{} if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: err.Error()}) return } resp, err := chat.ListMessages(c, req) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, chat.ErrorResp{Err: err.Error()}) klog.Infof("error resp: %v", err) return } @@ -166,23 +213,35 @@ func historyHandler() gin.HandlerFunc { } } +// @Summary get one message references +// @Schemes +// @Description get one message's references +// @Tags application +// @Accept json +// @Produce json +// @Param messageID path string true "messageID" +// @Param request body chat.MessageReqBody true "query params" +// @Success 200 {object} []retriever.Reference +// @Failure 400 {object} chat.ErrorResp +// @Failure 500 {object} chat.ErrorResp +// @Router /messages/:messageID/references [post] func referenceHandler() gin.HandlerFunc { return func(c *gin.Context) { messageID := c.Param("messageID") if messageID == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "messageID is required"}) + c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: "messageID is required"}) return } req := chat.MessageReqBody{ MessageID: messageID, } if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: err.Error()}) return } resp, err := chat.GetMessageReferences(c, req) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + c.JSON(http.StatusInternalServerError, chat.ErrorResp{Err: err.Error()}) klog.Infof("error resp: %v", err) return } @@ -190,11 +249,11 @@ func referenceHandler() gin.HandlerFunc { } } -func RegisterChat(g *gin.RouterGroup, conf config.ServerConfig) { +func registerChat(g *gin.RouterGroup, conf config.ServerConfig) { g.POST("", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), chatHandler()) // chat with bot - g.POST("/conversations", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), listConversationHandler()) // list conversations - g.DELETE("/conversations/:conversionID", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), deleteConversationHandler()) // delete conversation + g.POST("/conversations", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), listConversationHandler()) // list conversations + g.DELETE("/conversations/:conversationID", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), deleteConversationHandler()) // delete conversation g.POST("/messages", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), historyHandler()) // messages history g.POST("/messages/:messageID/references", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), referenceHandler()) // messages reference diff --git a/apiserver/service/router.go b/apiserver/service/router.go index be0d6f8ee..795917074 100644 --- a/apiserver/service/router.go +++ b/apiserver/service/router.go @@ -20,8 +20,11 @@ import ( "net/http" "github.com/gin-gonic/gin" + swaggerfiles "github.com/swaggo/files" + ginSwagger "github.com/swaggo/gin-swagger" "github.com/kubeagi/arcadia/apiserver/config" + "github.com/kubeagi/arcadia/apiserver/docs" "github.com/kubeagi/arcadia/apiserver/pkg/oidc" ) @@ -49,12 +52,15 @@ func NewServerAndRun(conf config.ServerConfig) { if conf.EnableOIDC { oidc.InitOIDCArgs(conf.IssuerURL, conf.MasterURL, conf.ClientSecret, conf.ClientID) } - bffGroup := r.Group("/bff") chatGroup := r.Group("/chat") RegisterMinIOAPI(bffGroup, conf) RegisterGraphQL(r, bffGroup, conf) - RegisterChat(chatGroup, conf) + registerChat(chatGroup, conf) + if conf.EnablePlayground { + docs.SwaggerInfo.BasePath = "/" + r.GET("swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler)) + } _ = r.Run(fmt.Sprintf("%s:%d", conf.Host, conf.Port)) } diff --git a/go.mod b/go.mod index 8561eddbb..3c51c1cd1 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,9 @@ require ( github.com/r3labs/sse/v2 v2.10.0 github.com/spf13/cobra v1.4.0 github.com/stretchr/testify v1.8.4 + github.com/swaggo/files v1.0.1 + github.com/swaggo/gin-swagger v1.6.0 + github.com/swaggo/swag v1.16.2 github.com/tmc/langchaingo v0.0.0-20231209214832-00f364f27fe2 github.com/valyala/fasthttp v1.49.0 github.com/vektah/gqlparser/v2 v2.5.10 @@ -27,31 +30,34 @@ require ( ) require ( + github.com/KyleBanks/depth v1.2.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.0 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect - github.com/bytedance/sonic v1.9.1 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/bytedance/sonic v1.10.2 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect + github.com/chenzhuoyu/iasm v0.9.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-jose/go-jose/v3 v3.0.0 // indirect + github.com/go-openapi/spec v0.20.13 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect + github.com/go-playground/validator/v10 v10.16.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.3 // indirect github.com/huandu/xstrings v1.3.3 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.0 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rs/xid v1.5.0 // indirect github.com/shopspring/decimal v1.2.0 // indirect @@ -59,9 +65,10 @@ require ( github.com/sosodev/duration v1.1.0 // indirect github.com/spf13/cast v1.3.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect go.starlark.net v0.0.0-20230302034142-4b1e35fe2254 // indirect - golang.org/x/arch v0.3.0 // indirect + golang.org/x/arch v0.6.0 // indirect + golang.org/x/tools v0.16.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) @@ -75,8 +82,6 @@ require ( github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/PuerkitoBio/goquery v1.8.1 // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/andybalholm/brotli v1.0.5 // indirect github.com/andybalholm/cascadia v1.3.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect @@ -89,9 +94,9 @@ require ( github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/go-logr/zapr v1.2.0 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.6 // indirect - github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/jsonpointer v0.20.2 // indirect + github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/swag v0.22.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect @@ -135,7 +140,7 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.1 // indirect - golang.org/x/crypto v0.16.0 // indirect + golang.org/x/crypto v0.17.0 // indirect golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea // indirect golang.org/x/net v0.19.0 // indirect golang.org/x/oauth2 v0.13.0 @@ -145,7 +150,7 @@ require ( golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.32.0 // indirect gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect @@ -162,4 +167,4 @@ require ( replace github.com/amikos-tech/chroma-go => github.com/bjwswang/chroma-go v0.0.0-20231011091545-0041221c9bb3 -replace github.com/tmc/langchaingo => github.com/Abirdcfly/langchaingo v0.0.0-20231215064216-74b306119ffa // TODO remove this replace after https://github.com/tmc/langchaingo/pull/411 is merged +replace github.com/tmc/langchaingo => github.com/Abirdcfly/langchaingo v0.0.0-20231225085033-c0e23696c583 // TODO remove this replace after https://github.com/tmc/langchaingo/pull/411 is merged and bug https://github.com/tmc/langchaingo/issues/455 is fixed diff --git a/go.sum b/go.sum index 7b8fbf9e2..78c102b42 100644 --- a/go.sum +++ b/go.sum @@ -47,8 +47,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/99designs/gqlgen v0.17.40 h1:/l8JcEVQ93wqIfmH9VS1jsAkwm6eAF1NwQn3N+SDqBY= github.com/99designs/gqlgen v0.17.40/go.mod h1:b62q1USk82GYIVjC60h02YguAZLqYZtvWml8KkhJps4= -github.com/Abirdcfly/langchaingo v0.0.0-20231215064216-74b306119ffa h1:IoYt2IecQ35790Pdhp73y7eSK+YuS3PonY0DkLOrlsw= -github.com/Abirdcfly/langchaingo v0.0.0-20231215064216-74b306119ffa/go.mod h1:l3ZkgXSZAighAgArxdo5QoveM4TfSob0u4yEJS8p5mY= +github.com/Abirdcfly/langchaingo v0.0.0-20231225085033-c0e23696c583 h1:hahXsvQ2l6Lug++Cgm8xyGBfTOxJzg0NSteNRuD7PQM= +github.com/Abirdcfly/langchaingo v0.0.0-20231225085033-c0e23696c583/go.mod h1:6gFzplGo6st/1G5y/Yv/7kGMI8NmFsCFImU24hqZ5Tw= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= @@ -68,6 +68,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/KawashiroNitori/butcher/v2 v2.0.1 h1:yJJyf9WO5BUvJxnxWAOAXQcY9+VqwnYcLV9MAgdrbtg= github.com/KawashiroNitori/butcher/v2 v2.0.1/go.mod h1:weH8qSjiTj6yGC956511noOaW4W6W9IW08Qhg78aVas= +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= @@ -79,9 +81,7 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= @@ -119,8 +119,9 @@ github.com/bjwswang/chroma-go v0.0.0-20231011091545-0041221c9bb3/go.mod h1:uJwgG github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= +github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE= +github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= @@ -129,8 +130,12 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= +github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= +github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0= +github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -192,11 +197,12 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= @@ -219,23 +225,26 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk= github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= +github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= -github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= +github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/spec v0.20.13 h1:XJDIN+dLH6vqXgafnl5SUIMnzaChQ6QTo0/UPMbkIaE= +github.com/go-openapi/spec v0.20.13/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.6 h1:dnqg1XfHXL9aBxSbktBqFR5CxVyVI+7fYWhAf1JOeTw= +github.com/go-openapi/swag v0.22.6/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE= +github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -405,15 +414,16 @@ github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGC github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -502,8 +512,8 @@ github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5h github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= +github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -605,16 +615,21 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= +github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= +github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M= +github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo= +github.com/swaggo/swag v1.16.2 h1:28Pp+8DkQoV+HLzLx8RGJZXNGKbFqnuvSbAAtoxiY04= +github.com/swaggo/swag v1.16.2/go.mod h1:6YzXnDcpr0767iOejs318CwYkCQqyGer6BizOg03f+E= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.49.0 h1:9FdvCpmxB74LH4dPb7IJ1cOSsluR07XG3I1txXWwJpE= @@ -692,8 +707,8 @@ go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc= +golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -707,8 +722,8 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -748,6 +763,7 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -792,7 +808,6 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -832,7 +847,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -888,7 +903,6 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -996,6 +1010,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1118,8 +1134,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba 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.27.1/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= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= @@ -1187,6 +1203,7 @@ k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdi k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc= k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/pkg/application/retriever/knowledgebaseretriever.go b/pkg/application/retriever/knowledgebaseretriever.go index 83214fc31..af79bd063 100644 --- a/pkg/application/retriever/knowledgebaseretriever.go +++ b/pkg/application/retriever/knowledgebaseretriever.go @@ -40,11 +40,16 @@ import ( ) type Reference struct { - Question string `json:"question"` - Answer string `json:"answer"` - Score float32 `json:"score"` - FilePath string `json:"file_path"` - LineNumber int `json:"line_number"` + // Question row + Question string `json:"question" example:"q: 旷工最小计算单位为多少天?"` + // Answer row + Answer string `json:"answer" example:"旷工最小计算单位为 0.5 天。"` + // vector search score + Score float32 `json:"score" example:"0.34"` + // file fullpath + FilePath string `json:"file_path" example:"dataset/dataset-playground/v1/qa.csv"` + // line number in the file + LineNumber int `json:"line_number" example:"7"` } type KnowledgeBaseRetriever struct { diff --git a/tests/example-test.sh b/tests/example-test.sh index 3b5a76305..b4f170e58 100755 --- a/tests/example-test.sh +++ b/tests/example-test.sh @@ -175,11 +175,11 @@ function getRespInAppChat() { appname=$1 namespace=$2 query=$3 - conversionID=$4 + conversationID=$4 testStream=$5 START_TIME=$(date +%s) while true; do - data=$(jq -n --arg appname "$appname" --arg query "$query" --arg namespace "$namespace" --arg conversionID "$conversionID" '{"query":$query,"response_mode":"blocking","conversion_id":$conversionID,"app_name":$appname, "app_namespace":$namespace}') + data=$(jq -n --arg appname "$appname" --arg query "$query" --arg namespace "$namespace" --arg conversationID "$conversationID" '{"query":$query,"response_mode":"blocking","conversation_id":$conversationID,"app_name":$appname, "app_namespace":$namespace}') resp=$(curl -s -XPOST http://127.0.0.1:8081/chat --data "$data") ai_data=$(echo $resp | jq -r '.message') references=$(echo $resp | jq -r '.references') @@ -190,11 +190,11 @@ function getRespInAppChat() { echo "👤: ${query}" echo "🤖: ${ai_data}" echo "🔗: ${references}" - resp_conversion_id=$(echo $resp | jq -r '.conversion_id') + resp_conversation_id=$(echo $resp | jq -r '.conversation_id') if [ $testStream == "true" ]; then info "just test stream mode" - data=$(jq -n --arg appname "$appname" --arg query "$query" --arg namespace "$namespace" --arg conversionID "$conversionID" '{"query":$query,"response_mode":"streaming","conversion_id":$conversionID,"app_name":$appname, "app_namespace":$namespace}') + data=$(jq -n --arg appname "$appname" --arg query "$query" --arg namespace "$namespace" --arg conversationID "$conversationID" '{"query":$query,"response_mode":"streaming","conversation_id":$conversationID,"app_name":$appname, "app_namespace":$namespace}') curl -s -XPOST http://127.0.0.1:8081/chat --data "$data" fi break @@ -297,28 +297,28 @@ waitCRDStatusReady "Application" "arcadia" "base-chat-with-knowledgebase" sleep 3 getRespInAppChat "base-chat-with-knowledgebase" "arcadia" "旷工最小计算单位为多少天?" "" "true" -info "8.3 conversion chat app" +info "8.3 conversation chat app" kubectl apply -f config/samples/app_llmchain_chat_with_bot.yaml waitCRDStatusReady "Application" "arcadia" "base-chat-with-bot" sleep 3 getRespInAppChat "base-chat-with-bot" "arcadia" "Hi I am Jim" "" "false" -getRespInAppChat "base-chat-with-bot" "arcadia" "What is my name?" ${resp_conversion_id} "false" +getRespInAppChat "base-chat-with-bot" "arcadia" "What is my name?" ${resp_conversation_id} "false" if [[ $resp != *"Jim"* ]]; then - echo "Because conversionWindowSize is enabled to be 2, llm should record history, but resp:"$resp "dont contains Jim" + echo "Because conversationWindowSize is enabled to be 2, llm should record history, but resp:"$resp "dont contains Jim" exit 1 fi -info "8.4 check conversion list and message history" +info "8.4 check conversation list and message history" curl -XPOST http://127.0.0.1:8081/chat/conversations --data '{"app_name": "base-chat-with-bot", "app_namespace": "arcadia"}' -data=$(jq -n --arg conversionID "$resp_conversion_id" '{"conversion_id":$conversionID, "app_name": "base-chat-with-bot", "app_namespace": "arcadia"}') +data=$(jq -n --arg conversationID "$resp_conversation_id" '{"conversation_id":$conversationID, "app_name": "base-chat-with-bot", "app_namespace": "arcadia"}') curl -XPOST http://127.0.0.1:8081/chat/messages --data "$data" # There is uncertainty in the AI replies, most of the time, it will pass the test, a small percentage of the time, the AI will call names in each reply, causing the test to fail, therefore, temporarily disable the following tests -#getRespInAppChat "base-chat-with-bot" "arcadia" "What is your model?" ${resp_conversion_id} "false" -#getRespInAppChat "base-chat-with-bot" "arcadia" "Does your model based on gpt-3.5?" ${resp_conversion_id} "false" -#getRespInAppChat "base-chat-with-bot" "arcadia" "When was the model you used released?" ${resp_conversion_id} "false" -#getRespInAppChat "base-chat-with-bot" "arcadia" "What is my name?" ${resp_conversion_id} "false" +#getRespInAppChat "base-chat-with-bot" "arcadia" "What is your model?" ${resp_conversation_id} "false" +#getRespInAppChat "base-chat-with-bot" "arcadia" "Does your model based on gpt-3.5?" ${resp_conversation_id} "false" +#getRespInAppChat "base-chat-with-bot" "arcadia" "When was the model you used released?" ${resp_conversation_id} "false" +#getRespInAppChat "base-chat-with-bot" "arcadia" "What is my name?" ${resp_conversation_id} "false" #if [[ $resp == *"Jim"* ]]; then -# echo "Because conversionWindowSize is enabled to be 2, and current is the 6th conversion, llm should not record My name, but resp:"$resp "still contains Jim" +# echo "Because conversationWindowSize is enabled to be 2, and current is the 6th conversation, llm should not record My name, but resp:"$resp "still contains Jim" # exit 1 #fi