From b1defed487a88840bebbe17261949bc1e9158a77 Mon Sep 17 00:00:00 2001 From: Rob-Powell <7034920+Rob-Powell@users.noreply.github.com> Date: Thu, 25 Jan 2024 00:29:40 +0000 Subject: [PATCH 01/23] feat: adding ability to run amplify command to generate code files --- .graphqlconfig.yml | 20 + lib/user-interface/react-app/schema.json | 4557 ---------------------- package-lock.json | 274 ++ package.json | 2 + 4 files changed, 296 insertions(+), 4557 deletions(-) create mode 100644 .graphqlconfig.yml delete mode 100644 lib/user-interface/react-app/schema.json diff --git a/.graphqlconfig.yml b/.graphqlconfig.yml new file mode 100644 index 000000000..ebd8b8e08 --- /dev/null +++ b/.graphqlconfig.yml @@ -0,0 +1,20 @@ +projects: + chatbot: + schemaPath: lib/chatbot-api/schema/schema.graphql + includes: + - lib/user-interface/react-app/src/graphql/*.ts + excludes: + - ./amplify/** + extensions: + amplify: + codeGenTarget: typescript + generatedFileName: lib/user-interface/react-app/src/API.ts + docsFilePath: lib/user-interface/react-app/src/graphql/ #The field is not configured correctly and needs to be changed + region: us-east-1 + apiId: null + frontend: javascript + framework: react + maxDepth: 2 +extensions: + amplify: + version: 3 diff --git a/lib/user-interface/react-app/schema.json b/lib/user-interface/react-app/schema.json deleted file mode 100644 index 76e29abd8..000000000 --- a/lib/user-interface/react-app/schema.json +++ /dev/null @@ -1,4557 +0,0 @@ -{ - "data" : { - "__schema" : { - "queryType" : { - "name" : "Query" - }, - "mutationType" : { - "name" : "Mutation" - }, - "subscriptionType" : { - "name" : "Subscription" - }, - "types" : [ { - "kind" : "OBJECT", - "name" : "Query", - "description" : null, - "fields" : [ { - "name" : "checkHealth", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "getUploadFileURL", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "FileUploadInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "FileUploadResult", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "listModels", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "Model", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "listWorkspaces", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "Workspace", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "getWorkspace", - "description" : null, - "args" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "Workspace", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "listRagEngines", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "RagEngine", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "performSemanticSearch", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "SemanticSearchInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "SemanticSearchResult", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "listSessions", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "Session", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "listEmbeddingModels", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "EmbeddingModel", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "calculateEmbeddings", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "CalculateEmbeddingsInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "Embedding", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "getSession", - "description" : null, - "args" : [ { - "name" : "id", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "Session", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "listKendraIndexes", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "KendraIndex", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "isKendraDataSynching", - "description" : null, - "args" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "listDocuments", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "ListDocumentsInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "DocumentsResult", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "getDocument", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "GetDocumentInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "Document", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "getRSSPosts", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "GetRSSPostsInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "DocumentsResult", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "listCrossEncoders", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "CrossEncoderData", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "rankPassages", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "RankPassagesInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "PassageRank", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "SCALAR", - "name" : "Boolean", - "description" : "Built-in Boolean", - "fields" : null, - "inputFields" : null, - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "FileUploadResult", - "description" : null, - "fields" : [ { - "name" : "url", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "fields", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "SCALAR", - "name" : "String", - "description" : "Built-in String", - "fields" : null, - "inputFields" : null, - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "FileUploadInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "fileName", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "Model", - "description" : null, - "fields" : [ { - "name" : "name", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "provider", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "interface", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "ragSupported", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "inputModalities", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "outputModalities", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "streaming", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "Workspace", - "description" : null, - "fields" : [ { - "name" : "id", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "name", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "formatVersion", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "engine", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "status", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "aossEngine", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "languages", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "hasIndex", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "embeddingsModelProvider", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "embeddingsModelName", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "embeddingsModelDimensions", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "crossEncoderModelName", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "crossEncoderModelProvider", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "metric", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "index", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "hybridSearch", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "chunkingStrategy", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "chunkSize", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "chunkOverlap", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "vectors", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "documents", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "sizeInBytes", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "kendraIndexId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "kendraIndexExternal", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "kendraUseAllData", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "createdAt", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "AWSDateTime", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "updatedAt", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "AWSDateTime", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "SCALAR", - "name" : "Int", - "description" : "Built-in Int", - "fields" : null, - "inputFields" : null, - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "SCALAR", - "name" : "AWSDateTime", - "description" : "The `AWSDateTime` scalar type provided by AWS AppSync, represents a valid ***extended*** [ISO 8601 DateTime](https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations) string. In other words, this scalar type accepts datetime strings of the form `YYYY-MM-DDThh:mm:ss.SSSZ`. The scalar can also accept \"negative years\" of the form `-YYYY` which correspond to years before `0000`. For example, \"**-2017-01-01T00:00Z**\" and \"**-9999-01-01T00:00Z**\" are both valid datetime strings. The field after the two digit seconds field is a nanoseconds field. It can accept between 1 and 9 digits. So, for example, \"**1970-01-01T12:00:00.2Z**\", \"**1970-01-01T12:00:00.277Z**\" and \"**1970-01-01T12:00:00.123456789Z**\" are all valid datetime strings. The seconds and nanoseconds fields are optional (the seconds field must be specified if the nanoseconds field is to be used). The [time zone offset](https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators) is compulsory for this scalar. The time zone offset must either be `Z` (representing the UTC time zone) or be in the format `±hh:mm:ss`. The seconds field in the timezone offset will be considered valid even though it is not part of the ISO 8601 standard.", - "fields" : null, - "inputFields" : null, - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "RagEngine", - "description" : null, - "fields" : [ { - "name" : "id", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "name", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "enabled", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "SemanticSearchResult", - "description" : null, - "fields" : [ { - "name" : "engine", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "workspaceId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "queryLanguage", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "supportedLanguages", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "detectedLanguages", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "DetectedLanguage", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "items", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "SemanticSearchItem", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "vectorSearchMetric", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "vectorSearchItems", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "SemanticSearchItem", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "keywordSearchItems", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "SemanticSearchItem", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "DetectedLanguage", - "description" : null, - "fields" : [ { - "name" : "code", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "score", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Float", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "SCALAR", - "name" : "Float", - "description" : "Built-in Float", - "fields" : null, - "inputFields" : null, - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "SemanticSearchItem", - "description" : null, - "fields" : [ { - "name" : "sources", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "chunkId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "workspaceId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "ID", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "documentId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "documentSubId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "documentSubType", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "documentType", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "path", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "language", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "title", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "content", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "contentComplement", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "vectorSearchScore", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Float", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "keywordSearchScore", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Float", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "score", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Float", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "SCALAR", - "name" : "ID", - "description" : "Built-in ID", - "fields" : null, - "inputFields" : null, - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "SemanticSearchInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "query", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "Session", - "description" : null, - "fields" : [ { - "name" : "id", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "title", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "startTime", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "AWSDateTime", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "history", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "SessionHistoryItem", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "SessionHistoryItem", - "description" : null, - "fields" : [ { - "name" : "type", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "content", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "metadata", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "EmbeddingModel", - "description" : null, - "fields" : [ { - "name" : "provider", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "name", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "dimensions", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "default", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "Embedding", - "description" : null, - "fields" : [ { - "name" : "passage", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "vector", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Float", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "CalculateEmbeddingsInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "provider", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "model", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "passages", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "KendraIndex", - "description" : null, - "fields" : [ { - "name" : "id", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "name", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "external", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "DocumentsResult", - "description" : null, - "fields" : [ { - "name" : "items", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "Document", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "lastDocumentId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "Document", - "description" : null, - "fields" : [ { - "name" : "workspaceId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "id", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "type", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "subType", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "status", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "title", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "path", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "sizeInBytes", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "vectors", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "subDocuments", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "crawlerProperties", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "OBJECT", - "name" : "CrawlerProperties", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "errors", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "createdAt", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "AWSDateTime", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "updatedAt", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "AWSDateTime", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "rssFeedId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "rssLastCheckedAt", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "AWSDateTime", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "CrawlerProperties", - "description" : null, - "fields" : [ { - "name" : "followLinks", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "limit", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "ListDocumentsInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "documentType", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "lastDocumentId", - "description" : null, - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "GetDocumentInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "documentId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "GetRSSPostsInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "documentId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "lastDocumentId", - "description" : null, - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "CrossEncoderData", - "description" : null, - "fields" : [ { - "name" : "provider", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "name", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "default", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "PassageRank", - "description" : null, - "fields" : [ { - "name" : "score", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Float", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "passage", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "RankPassagesInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "provider", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "model", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "reference", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "passages", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "Mutation", - "description" : null, - "fields" : [ { - "name" : "createKendraWorkspace", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "CreateWorkspaceKendraInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "Workspace", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "createOpenSearchWorkspace", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "CreateWorkspaceOpenSearchInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "Workspace", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "createAuroraWorkspace", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "CreateWorkspaceAuroraInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "Workspace", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "startKendraDataSync", - "description" : null, - "args" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "deleteWorkspace", - "description" : null, - "args" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "addTextDocument", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "TextDocumentInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "DocumentResult", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "addQnADocument", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "QnADocumentInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "DocumentResult", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "setDocumentSubscriptionStatus", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "DocumentSubscriptionStatusInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "DocumentResult", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "addWebsite", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "WebsiteInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "DocumentResult", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "addRssFeed", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "RssFeedInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "DocumentResult", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "updateRssFeed", - "description" : null, - "args" : [ { - "name" : "input", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "INPUT_OBJECT", - "name" : "RssFeedInput", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "DocumentResult", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "deleteUserSessions", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "DeleteSessionResult", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "deleteSession", - "description" : null, - "args" : [ { - "name" : "id", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "DeleteSessionResult", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "sendQuery", - "description" : " Real-time", - "args" : [ { - "name" : "data", - "description" : null, - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "publishResponse", - "description" : null, - "args" : [ { - "name" : "sessionId", - "description" : null, - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "defaultValue" : null - }, { - "name" : "userId", - "description" : null, - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "defaultValue" : null - }, { - "name" : "data", - "description" : null, - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "Channel", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "CreateWorkspaceKendraInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "name", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "kind", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "kendraIndexId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "useAllData", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "CreateWorkspaceOpenSearchInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "name", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "kind", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "embeddingsModelProvider", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "embeddingsModelName", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "crossEncoderModelProvider", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "crossEncoderModelName", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "languages", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - } - } - }, - "defaultValue" : null - }, { - "name" : "hybridSearch", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "chunkingStrategy", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "chunkSize", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "chunkOverlap", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "CreateWorkspaceAuroraInput", - "description" : " Workspaces", - "fields" : null, - "inputFields" : [ { - "name" : "name", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "kind", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "embeddingsModelProvider", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "embeddingsModelName", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "crossEncoderModelProvider", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "crossEncoderModelName", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "languages", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - } - } - }, - "defaultValue" : null - }, { - "name" : "metric", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "index", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "hybridSearch", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "chunkingStrategy", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "chunkSize", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "chunkOverlap", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "DocumentResult", - "description" : null, - "fields" : [ { - "name" : "workspaceId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "documentId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "status", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "TextDocumentInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "title", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "content", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "QnADocumentInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "question", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "answer", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "DocumentSubscriptionStatusInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "documentId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "status", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "WebsiteInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "sitemap", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "address", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "followLinks", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "limit", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "INPUT_OBJECT", - "name" : "RssFeedInput", - "description" : null, - "fields" : null, - "inputFields" : [ { - "name" : "workspaceId", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "address", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "limit", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Int", - "ofType" : null - } - }, - "defaultValue" : null - }, { - "name" : "title", - "description" : null, - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "defaultValue" : null - }, { - "name" : "followLinks", - "description" : null, - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "interfaces" : null, - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "DeleteSessionResult", - "description" : null, - "fields" : [ { - "name" : "id", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "deleted", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "Channel", - "description" : null, - "fields" : [ { - "name" : "data", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "sessionId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "userId", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "Subscription", - "description" : null, - "fields" : [ { - "name" : "receiveMessages", - "description" : null, - "args" : [ { - "name" : "sessionId", - "description" : null, - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "defaultValue" : null - } ], - "type" : { - "kind" : "OBJECT", - "name" : "Channel", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "__Schema", - "description" : "A GraphQL Introspection defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, the entry points for query, mutation, and subscription operations.", - "fields" : [ { - "name" : "types", - "description" : "A list of all types supported by this server.", - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "__Type", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "queryType", - "description" : "The type that query operations will be rooted at.", - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "__Type", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "mutationType", - "description" : "If this server supports mutation, the type that mutation operations will be rooted at.", - "args" : [ ], - "type" : { - "kind" : "OBJECT", - "name" : "__Type", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "directives", - "description" : "'A list of all directives supported by this server.", - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "__Directive", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "subscriptionType", - "description" : "'If this server support subscription, the type that subscription operations will be rooted at.", - "args" : [ ], - "type" : { - "kind" : "OBJECT", - "name" : "__Type", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "__Type", - "description" : null, - "fields" : [ { - "name" : "kind", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "ENUM", - "name" : "__TypeKind", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "name", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "description", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "fields", - "description" : null, - "args" : [ { - "name" : "includeDeprecated", - "description" : null, - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "defaultValue" : "false" - } ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "__Field", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "interfaces", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "__Type", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "possibleTypes", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "__Type", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "enumValues", - "description" : null, - "args" : [ { - "name" : "includeDeprecated", - "description" : null, - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "defaultValue" : "false" - } ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "__EnumValue", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "inputFields", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "__InputValue", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "ofType", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "OBJECT", - "name" : "__Type", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "ENUM", - "name" : "__TypeKind", - "description" : "An enum describing what kind of type a given __Type is", - "fields" : null, - "inputFields" : null, - "interfaces" : null, - "enumValues" : [ { - "name" : "SCALAR", - "description" : "Indicates this type is a scalar.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "OBJECT", - "description" : "Indicates this type is an object. `fields` and `interfaces` are valid fields.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "INTERFACE", - "description" : "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "UNION", - "description" : "Indicates this type is a union. `possibleTypes` is a valid field.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "ENUM", - "description" : "Indicates this type is an enum. `enumValues` is a valid field.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "INPUT_OBJECT", - "description" : "Indicates this type is an input object. `inputFields` is a valid field.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "LIST", - "description" : "Indicates this type is a list. `ofType` is a valid field.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "NON_NULL", - "description" : "Indicates this type is a non-null. `ofType` is a valid field.", - "isDeprecated" : false, - "deprecationReason" : null - } ], - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "__Field", - "description" : null, - "fields" : [ { - "name" : "name", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "description", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "args", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "__InputValue", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "type", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "__Type", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "isDeprecated", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "deprecationReason", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "__InputValue", - "description" : null, - "fields" : [ { - "name" : "name", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "description", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "type", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "__Type", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "defaultValue", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "__EnumValue", - "description" : null, - "fields" : [ { - "name" : "name", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "description", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "isDeprecated", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "deprecationReason", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "OBJECT", - "name" : "__Directive", - "description" : null, - "fields" : [ { - "name" : "name", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "description", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "locations", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "ENUM", - "name" : "__DirectiveLocation", - "ofType" : null - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "args", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "OBJECT", - "name" : "__InputValue", - "ofType" : null - } - } - } - }, - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "onOperation", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : true, - "deprecationReason" : "Use `locations`." - }, { - "name" : "onFragment", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : true, - "deprecationReason" : "Use `locations`." - }, { - "name" : "onField", - "description" : null, - "args" : [ ], - "type" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - }, - "isDeprecated" : true, - "deprecationReason" : "Use `locations`." - } ], - "inputFields" : null, - "interfaces" : [ ], - "enumValues" : null, - "possibleTypes" : null - }, { - "kind" : "ENUM", - "name" : "__DirectiveLocation", - "description" : "An enum describing valid locations where a directive can be placed", - "fields" : null, - "inputFields" : null, - "interfaces" : null, - "enumValues" : [ { - "name" : "QUERY", - "description" : "Indicates the directive is valid on queries.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "MUTATION", - "description" : "Indicates the directive is valid on mutations.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "FIELD", - "description" : "Indicates the directive is valid on fields.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "FRAGMENT_DEFINITION", - "description" : "Indicates the directive is valid on fragment definitions.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "FRAGMENT_SPREAD", - "description" : "Indicates the directive is valid on fragment spreads.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "INLINE_FRAGMENT", - "description" : "Indicates the directive is valid on inline fragments.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "SCHEMA", - "description" : "Indicates the directive is valid on a schema SDL definition.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "SCALAR", - "description" : "Indicates the directive is valid on a scalar SDL definition.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "OBJECT", - "description" : "Indicates the directive is valid on an object SDL definition.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "FIELD_DEFINITION", - "description" : "Indicates the directive is valid on a field SDL definition.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "ARGUMENT_DEFINITION", - "description" : "Indicates the directive is valid on a field argument SDL definition.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "INTERFACE", - "description" : "Indicates the directive is valid on an interface SDL definition.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "UNION", - "description" : "Indicates the directive is valid on an union SDL definition.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "ENUM", - "description" : "Indicates the directive is valid on an enum SDL definition.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "ENUM_VALUE", - "description" : "Indicates the directive is valid on an enum value SDL definition.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "INPUT_OBJECT", - "description" : "Indicates the directive is valid on an input object SDL definition.", - "isDeprecated" : false, - "deprecationReason" : null - }, { - "name" : "INPUT_FIELD_DEFINITION", - "description" : "Indicates the directive is valid on an input object field SDL definition.", - "isDeprecated" : false, - "deprecationReason" : null - } ], - "possibleTypes" : null - } ], - "directives" : [ { - "name" : "include", - "description" : "Directs the executor to include this field or fragment only when the `if` argument is true", - "locations" : [ "FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT" ], - "args" : [ { - "name" : "if", - "description" : "Included when true.", - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "onOperation" : false, - "onFragment" : true, - "onField" : true - }, { - "name" : "skip", - "description" : "Directs the executor to skip this field or fragment when the `if`'argument is true.", - "locations" : [ "FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT" ], - "args" : [ { - "name" : "if", - "description" : "Skipped when true.", - "type" : { - "kind" : "NON_NULL", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "Boolean", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "onOperation" : false, - "onFragment" : true, - "onField" : true - }, { - "name" : "defer", - "description" : "This directive allows results to be deferred during execution", - "locations" : [ "FIELD" ], - "args" : [ ], - "onOperation" : false, - "onFragment" : false, - "onField" : true - }, { - "name" : "aws_iam", - "description" : "Tells the service this field/object has access authorized by sigv4 signing.", - "locations" : [ "OBJECT", "FIELD_DEFINITION" ], - "args" : [ ], - "onOperation" : false, - "onFragment" : false, - "onField" : false - }, { - "name" : "aws_publish", - "description" : "Tells the service which subscriptions will be published to when this mutation is called. This directive is deprecated use @aws_susbscribe directive instead.", - "locations" : [ "FIELD_DEFINITION" ], - "args" : [ { - "name" : "subscriptions", - "description" : "List of subscriptions which will be published to when this mutation is called.", - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "onOperation" : false, - "onFragment" : false, - "onField" : false - }, { - "name" : "aws_oidc", - "description" : "Tells the service this field/object has access authorized by an OIDC token.", - "locations" : [ "OBJECT", "FIELD_DEFINITION" ], - "args" : [ ], - "onOperation" : false, - "onFragment" : false, - "onField" : false - }, { - "name" : "deprecated", - "description" : null, - "locations" : [ "FIELD_DEFINITION", "ENUM_VALUE" ], - "args" : [ { - "name" : "reason", - "description" : null, - "type" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - }, - "defaultValue" : "\"No longer supported\"" - } ], - "onOperation" : false, - "onFragment" : false, - "onField" : false - }, { - "name" : "aws_cognito_user_pools", - "description" : "Tells the service this field/object has access authorized by a Cognito User Pools token.", - "locations" : [ "OBJECT", "FIELD_DEFINITION" ], - "args" : [ { - "name" : "cognito_groups", - "description" : "List of cognito user pool groups which have access on this field", - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "onOperation" : false, - "onFragment" : false, - "onField" : false - }, { - "name" : "aws_auth", - "description" : "Directs the schema to enforce authorization on a field", - "locations" : [ "FIELD_DEFINITION" ], - "args" : [ { - "name" : "cognito_groups", - "description" : "List of cognito user pool groups which have access on this field", - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "onOperation" : false, - "onFragment" : false, - "onField" : false - }, { - "name" : "aws_api_key", - "description" : "Tells the service this field/object has access authorized by an API key.", - "locations" : [ "OBJECT", "FIELD_DEFINITION" ], - "args" : [ ], - "onOperation" : false, - "onFragment" : false, - "onField" : false - }, { - "name" : "aws_lambda", - "description" : "Tells the service this field/object has access authorized by a Lambda Authorizer.", - "locations" : [ "OBJECT", "FIELD_DEFINITION" ], - "args" : [ ], - "onOperation" : false, - "onFragment" : false, - "onField" : false - }, { - "name" : "aws_subscribe", - "description" : "Tells the service which mutation triggers this subscription.", - "locations" : [ "FIELD_DEFINITION" ], - "args" : [ { - "name" : "mutations", - "description" : "List of mutations which will trigger this subscription when they are called.", - "type" : { - "kind" : "LIST", - "name" : null, - "ofType" : { - "kind" : "SCALAR", - "name" : "String", - "ofType" : null - } - }, - "defaultValue" : null - } ], - "onOperation" : false, - "onFragment" : false, - "onField" : false - } ] - } - } -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 305166515..693a9a844 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "aws-genai-llm-chatbot": "bin/aws-genai-llm-chatbot.js" }, "devDependencies": { + "@aws-amplify/cli": "^12.10.1", "@aws-lambda-powertools/batch": "^1.14.1", "@aws-lambda-powertools/logger": "^1.14.1", "@aws-sdk/credential-provider-node": "^3.441.0", @@ -227,6 +228,24 @@ "@algolia/requester-common": "4.20.0" } }, + "node_modules/@aws-amplify/cli": { + "version": "12.10.1", + "resolved": "https://registry.npmjs.org/@aws-amplify/cli/-/cli-12.10.1.tgz", + "integrity": "sha512-vwb4rU340V5ZLAykyffX9yuZqqYk14ta3Z6zqNvZVmb8QGKdt8uuhEyKRrG0rYx3JbiB4yFWp3qL31SqUBKX2Q==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "axios": "^1.6.2", + "rimraf": "^3.0.2", + "tar-stream": "^2.2.0" + }, + "bin": { + "amplify": "lib/run.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@aws-cdk/asset-awscli-v1": { "version": "2.2.201", "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.201.tgz", @@ -2590,6 +2609,12 @@ "node": ">=8" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "node_modules/aws-cdk": { "version": "2.114.1", "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.114.1.tgz", @@ -2945,12 +2970,54 @@ "node": ">= 6" } }, + "node_modules/axios": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.6.tgz", + "integrity": "sha512-XZLZDFfXKM9U/Y/B4nNynfCRUqNyVZ4sBC/n9GDRCkq9vd2mIvKjKKsbIh1WPmHmNbg6ND7cTBY3Y2+u1G3/2Q==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/bowser": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", @@ -2979,6 +3046,30 @@ "node": ">=8" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -3036,6 +3127,18 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", @@ -3107,6 +3210,15 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -3140,6 +3252,15 @@ "node": ">=6.0.0" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enquirer": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", @@ -3473,6 +3594,46 @@ "tabbable": "^6.2.0" } }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3584,10 +3745,31 @@ "node": ">=8" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, "engines": { "node": ">= 4" } @@ -3815,6 +3997,27 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4047,6 +4250,12 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -4076,6 +4285,20 @@ } ] }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4174,6 +4397,26 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/search-insights": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.10.0.tgz", @@ -4264,6 +4507,15 @@ "source-map": "^0.6.0" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4305,6 +4557,22 @@ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", "dev": true }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -4430,6 +4698,12 @@ "punycode": "^2.1.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", diff --git a/package.json b/package.json index bb3423c03..47c45c060 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "build": "tsc", "watch": "tsc -w", "cdk": "cdk", + "gen": "npx @aws-amplify/cli codegen", "create": "node ./cli/magic.js create", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "format": "npx prettier --ignore-path .gitignore --write \"**/*.+(js|ts|jsx|tsx|json|css)\"", @@ -17,6 +18,7 @@ "docs:preview": "vitepress preview docs" }, "devDependencies": { + "@aws-amplify/cli": "^12.10.1", "@aws-lambda-powertools/batch": "^1.14.1", "@aws-lambda-powertools/logger": "^1.14.1", "@aws-sdk/credential-provider-node": "^3.441.0", From afad924a1eb87c2c531227fc9cc160a553562c08 Mon Sep 17 00:00:00 2001 From: Daisy Riley Date: Thu, 25 Jan 2024 14:49:06 +0000 Subject: [PATCH 02/23] chore(gh-actions): add new GitHub action to mark issues stale after 60 days of inactivity and close after 30 days --- .github/workflows/stale.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 000000000..2a69fbbe9 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,24 @@ +name: Close stale issues + +on: + schedule: + - cron: "38 1 * * *" + +permissions: + issues: write + pull-requests: write + +jobs: + close-issues: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + days-before-issue-stale: 60 + days-before-issue-close: 30 + stale-issue-label: "stale" + stale-issue-message: "This issue is stale because it has been open for 60 days with no activity." + close-issue-message: "This issue was closed because it has been inactive for 30 days since being marked as stale." + days-before-pr-stale: -1 + days-before-pr-close: -1 + repo-token: ${{ secrets.GITHUB_TOKEN }} From 8ae3cc4c2ff3bd4e4c84f78a7588f598677aa833 Mon Sep 17 00:00:00 2001 From: Ronald Luitwieler Date: Thu, 25 Jan 2024 11:09:20 +0100 Subject: [PATCH 03/23] Update README.md for additional models support Extra note on customizing the prompt when RAG is used/enabled. --- lib/model-interfaces/langchain/README.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/model-interfaces/langchain/README.md b/lib/model-interfaces/langchain/README.md index 8afa75a4f..f43574f1d 100644 --- a/lib/model-interfaces/langchain/README.md +++ b/lib/model-interfaces/langchain/README.md @@ -27,8 +27,9 @@ class GPTAdapter(ModelAdapter): return ChatOpenAI(model_name=self.model_id, temperature=0, **model_kwargs) - # (OPTIONAL) 3.If you need to override the default prompt, override the get_prompt method. - # If not you can remove this and leverage the get_prompt from the base adapater. + # (OPTIONAL) 3.If you need to override the default prompt, override the get_prompt and get_qa_prompt methods. + # The get_qa_prompt is only used when RAG is enabled. + # If not you can remove this and leverage the get_prompt and get_qa_prompts from the base adapater. # must return a PromptTemplate def get_prompt(self): template = """The following is a friendly conversation between a human and an AI. If the AI does not know the answer to a question, it truthfully says it does not know. @@ -46,6 +47,19 @@ class GPTAdapter(ModelAdapter): prompt_template = PromptTemplate(**prompt_template_args) return prompt_template + + def get_qa_prompt(self): + template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer. + + {context} + + Question: {question} + Helpful Answer:""" + qa_prompt_template = PromptTemplate( + template=template, input_variables=["context", "question"] + ) + + return qa_prompt_template ... # 4. Finally, Register the adapter to match the model id coming from the select UI From 329d7e8bb60f4974fb4e0227ac014e182a78b329 Mon Sep 17 00:00:00 2001 From: Rob-Powell <7034920+Rob-Powell@users.noreply.github.com> Date: Tue, 23 Jan 2024 10:35:30 +0000 Subject: [PATCH 04/23] docs are using old architecture diagram without appsync --- docs/about/assets/architecture.png | Bin 99013 -> 111254 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/about/assets/architecture.png b/docs/about/assets/architecture.png index ce39db2903ab837e87ba0cb3a3cfd50f25664d10..007dfce296fed9111cc480eb442757419f94e9e0 100644 GIT binary patch literal 111254 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 S_b}1GA0>I%-3nQ=kpBl|e?cn% literal 99013 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 From c96dfb75bf0607c96e0abb97a5d2608686068b18 Mon Sep 17 00:00:00 2001 From: Bigad Soleiman Date: Thu, 25 Jan 2024 17:24:19 +0000 Subject: [PATCH 05/23] Update docs --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 3b5846124..ba6614abd 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,7 +2,7 @@ layout: home hero: - name: "AWS GenAI LLM Chatbot" + name: "AWS GenAI Chatbot" text: "Deploying a Multi-Model and Multi-RAG Powered Chatbot Using AWS CDK on AWS" actions: - theme: brand From 6bbb14053a2a899ee84e7e7a399c8e29b78cdd74 Mon Sep 17 00:00:00 2001 From: Bigad Soleiman Date: Mon, 29 Jan 2024 00:25:47 +0000 Subject: [PATCH 06/23] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48faac89a..db8123943 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![GitHub star chart](https://img.shields.io/github/stars/aws-samples/aws-genai-llm-chatbot?style=social)](https://star-history.com/#aws-samples/aws-genai-llm-chatbot) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -[![Deploy with GitHub Codespaces](https://github.com/codespaces/badge.svg)](#deploy-with-github-codespaces) +[![Deploy with GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://aws-samples.github.io/aws-genai-llm-chatbot/guide/deploy.html#deploy-with-github-codespaces) #### [Full documentation](https://aws-samples.github.io/aws-genai-llm-chatbot/) From bb77eea0907f3385c207fd8488ecf783af06b5fe Mon Sep 17 00:00:00 2001 From: Daisy Riley Date: Mon, 29 Jan 2024 11:15:31 +0000 Subject: [PATCH 07/23] docs: change docs link to button to make it clearer to users --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index db8123943..a7be84535 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Deploy with GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://aws-samples.github.io/aws-genai-llm-chatbot/guide/deploy.html#deploy-with-github-codespaces) -#### [Full documentation](https://aws-samples.github.io/aws-genai-llm-chatbot/) +[![Full Documentation](https://img.shields.io/badge/Full%20Documentation-blue?style=for-the-badge&logo=Vite&logoColor=white)](https://aws-samples.github.io/aws-genai-llm-chatbot/) ![sample](docs/about/assets/chabot-sample.gif "AWS GenAI Chatbot") From ecf0234aa43587e08570c80c5f6f4e21d16a9cf8 Mon Sep 17 00:00:00 2001 From: Manuwai Korber Date: Fri, 22 Dec 2023 01:18:41 +0000 Subject: [PATCH 08/23] Feature: add private chatbot deployment option --- bin/config.ts | 9 +- cli/magic-create.ts | 43 ++- docs/.vitepress/config.mts | 1 + docs/documentation/private-chatbot.md | 28 ++ docs/guide/deploy.md | 1 + lib/aws-genai-llm-chatbot-stack.ts | 33 +++ lib/chatbot-api/appsync-ws.ts | 2 + lib/chatbot-api/index.ts | 1 + lib/shared/index.ts | 85 +++++- lib/shared/types.ts | 11 + lib/user-interface/index.ts | 112 ++------ lib/user-interface/private-website.ts | 257 ++++++++++++++++++ lib/user-interface/public-website.ts | 155 +++++++++++ lib/user-interface/react-app/src/app.tsx | 9 +- .../src/components/app-configured.tsx | 2 +- 15 files changed, 642 insertions(+), 107 deletions(-) create mode 100644 docs/documentation/private-chatbot.md create mode 100644 lib/user-interface/private-website.ts create mode 100644 lib/user-interface/public-website.ts diff --git a/bin/config.ts b/bin/config.ts index 75353892c..c43f31d0e 100644 --- a/bin/config.ts +++ b/bin/config.ts @@ -8,10 +8,12 @@ export function getConfig(): SystemConfig { // Default config return { prefix: "", - /*vpc: { - vpcId: "vpc-00000000000000000", - createVpcEndpoints: true, + /* vpc: { + vpcId: "vpc-00000000000000000", + createVpcEndpoints: true, },*/ + privateWebsite: false, + certificate : "", bedrock: { enabled: true, region: SupportedRegion.US_EAST_1, @@ -32,6 +34,7 @@ export function getConfig(): SystemConfig { kendra: { enabled: false, createIndex: false, + enterprise: false }, }, embeddingsModels: [ diff --git a/cli/magic-create.ts b/cli/magic-create.ts index d36a1864d..671ec8059 100644 --- a/cli/magic-create.ts +++ b/cli/magic-create.ts @@ -9,6 +9,7 @@ import { SupportedRegion, SupportedSageMakerModels, SystemConfig, + SupportedBedrockRegion } from "../lib/shared/types"; import { LIB_VERSION } from "./version.js"; import * as fs from "fs"; @@ -57,6 +58,9 @@ const embeddingModels = [ fs.readFileSync("./bin/config.json").toString("utf8") ); options.prefix = config.prefix; + options.privateWebsite = config.privateWebsite; + options.certificate = config.certificate; + options.domain = config.domain; options.bedrockEnable = config.bedrock?.enabled; options.bedrockRegion = config.bedrock?.region; options.bedrockRoleArn = config.bedrock?.roleArn; @@ -113,6 +117,34 @@ async function processCreateOptions(options: any): Promise { initial: options.prefix, askAnswered: false, }, + { + type: "confirm", + name: "privateWebsite", + message: "Do you want to deploy a private website? I.e only accessible in VPC", + initial: + options.privateWebsite || + false, + }, + { + type: "input", + name: "certificate", + message: "ACM certificate ARN", + initial: + options.certificate, + skip(): boolean { + return !(this as any).state.answers.privateWebsite; + }, + }, + { + type: "input", + name: "domain", + message: "Domain for private website", + initial: + options.domain, + skip(): boolean { + return !(this as any).state.answers.privateWebsite; + }, + }, { type: "confirm", name: "bedrockEnable", @@ -123,13 +155,7 @@ async function processCreateOptions(options: any): Promise { type: "select", name: "bedrockRegion", message: "Region where Bedrock is available", - choices: [ - SupportedRegion.US_EAST_1, - SupportedRegion.US_WEST_2, - SupportedRegion.EU_CENTRAL_1, - SupportedRegion.AP_SOUTHEAST_1, - SupportedRegion.AP_NORTHEAST_1, - ], + choices: Object.values(SupportedBedrockRegion), initial: options.bedrockRegion ?? "us-east-1", skip() { return !(this as any).state.answers.bedrockEnable; @@ -310,6 +336,9 @@ async function processCreateOptions(options: any): Promise { // Create the config object const config = { prefix: answers.prefix, + privateWebsite: answers.privateWebsite, + certificate: answers.certificate, + domain: answers.domain, bedrock: answers.bedrockEnable ? { enabled: answers.bedrockEnable, diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 2111e18e0..c595cc5ab 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -44,6 +44,7 @@ export default defineConfig({ { text: 'Documentation', items: [ + { text: 'Private Chatbot', link: '/documentation/private-chatbot' }, { text: 'Model Requirements', link: '/documentation/model-requirements' }, { text: 'Inference Script', link: '/documentation/inference-script' }, { text: 'Document Retrieval', link: '/documentation/retriever' }, diff --git a/docs/documentation/private-chatbot.md b/docs/documentation/private-chatbot.md new file mode 100644 index 000000000..e074c5903 --- /dev/null +++ b/docs/documentation/private-chatbot.md @@ -0,0 +1,28 @@ +# Private Chatbot + +Allows the deployment of a private chatbot via the 'npm run create' CLI setup. + +- VPC only accessible website with an Application Load Balancer in front of an S3 hosted website. +- Private Appsync APIs and Web Sockets +- VPC endpoints for AWS services +- Utilises a AWS Private CA certifice +- Utilises a Amazon Route 53 Private Hosted Zone and Domain + + +### Prerequisites: Private Chatbot Deployment +1. [AWS Private CA issued ACM certificate](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-private.html) for your chosen domain. (i.e. chatbot.example.org) +2. A Route 53 [Private Hosted Zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-private.html) (i.e. for example.org) + +### During 'npm run create' +```shellsession +$ ✔ Do you want to deploy a private website? I.e only accessible in VPC (Y/n) · +true +$ ✔ ACM certificate ARN · +arn:aws:acm:us-east-1:1234567890:certificate/12345678-1234-1234-1234-12345678 +$ ✔ Domain for private website · +chatbot.example.org +``` + +### After Private Deployment: +1. In Route 53 [link the created VPC to the Private Hosted Zone (PHZ)](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zone-private-associate-vpcs.html) +2. In the PHZ, [add an "A Record"](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-elb-load-balancer.html) with your chosen subdomain (i.e. chatbot.example.org) that points to the website Application Load Balancer Alias. diff --git a/docs/guide/deploy.md b/docs/guide/deploy.md index cbfd49663..022f617ab 100644 --- a/docs/guide/deploy.md +++ b/docs/guide/deploy.md @@ -107,6 +107,7 @@ You'll be prompted to configure the different aspects of the solution, such as: - The LLMs or MLMs to enable (we support all models provided by Bedrock along with SageMaker hosted Idefics, FalconLite, Mistral and more to come) - Setup of the RAG system: engine selection (i.e. Aurora w/ pgvector, OpenSearch, Kendra..) embeddings selection and more to come. +- Private Chatbot: Limit accessibility to website and backend to VPC. When done, answer `Y` to create a new configuration. diff --git a/lib/aws-genai-llm-chatbot-stack.ts b/lib/aws-genai-llm-chatbot-stack.ts index ad0f679b4..589fa0906 100644 --- a/lib/aws-genai-llm-chatbot-stack.ts +++ b/lib/aws-genai-llm-chatbot-stack.ts @@ -415,5 +415,38 @@ export class AwsGenAILLMChatbotStack extends cdk.Stack { reason: "Not yet upgraded from Python 3.11 to 3.12.", }, ]); + + if (props.config.privateWebsite) { + NagSuppressions.addResourceSuppressionsByPath( + this, + [ + `/${this.stackName}/UserInterface/PrivateWebsite/DescribeNetworkInterfaces-0/CustomResourcePolicy/Resource`, + `/${this.stackName}/UserInterface/PrivateWebsite/DescribeNetworkInterfaces-1/CustomResourcePolicy/Resource`, + `/${this.stackName}/UserInterface/PrivateWebsite/DescribeNetworkInterfaces-2/CustomResourcePolicy/Resource`, + `/${this.stackName}/UserInterface/PrivateWebsite/describeVpcEndpoints/CustomResourcePolicy/Resource`, + ], + [ + { + id: "AwsSolutions-IAM5", + reason: + "Custom Resource requires permissions to Describe VPC Endpoint Network Interfaces", + }, + ] + ); + NagSuppressions.addResourceSuppressionsByPath( + this, + [ + `/${this.stackName}/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource` + ], + [ + { + id: "AwsSolutions-IAM4", + reason: + "IAM role implicitly created by CDK.", + }, + ] + ); + + } } } diff --git a/lib/chatbot-api/appsync-ws.ts b/lib/chatbot-api/appsync-ws.ts index 20cb43240..96668ac0c 100644 --- a/lib/chatbot-api/appsync-ws.ts +++ b/lib/chatbot-api/appsync-ws.ts @@ -42,6 +42,7 @@ export class RealtimeResolvers extends Construct { SNS_TOPIC_ARN: props.topic.topicArn, }, layers: [props.shared.powerToolsLayer], + vpc: props.shared.vpc }); const outgoingMessageHandler = new NodejsFunction( @@ -58,6 +59,7 @@ export class RealtimeResolvers extends Construct { environment: { GRAPHQL_ENDPOINT: props.api.graphqlUrl, }, + vpc: props.shared.vpc } ); diff --git a/lib/chatbot-api/index.ts b/lib/chatbot-api/index.ts index 155894112..cf70c51cc 100644 --- a/lib/chatbot-api/index.ts +++ b/lib/chatbot-api/index.ts @@ -79,6 +79,7 @@ export class ChatBotApi extends Construct { role: loggingRole, }, xrayEnabled: true, + visibility: props.config.privateWebsite ? appsync.Visibility.PRIVATE : appsync.Visibility.GLOBAL }); new ApiResolvers(this, "RestApi", { diff --git a/lib/shared/index.ts b/lib/shared/index.ts index 155c9d670..2bcc6742a 100644 --- a/lib/shared/index.ts +++ b/lib/shared/index.ts @@ -7,7 +7,7 @@ import * as logs from "aws-cdk-lib/aws-logs"; import { Construct } from "constructs"; import * as path from "path"; import { Layer } from "../layer"; -import { SystemConfig } from "./types"; +import { SystemConfig, SupportedBedrockRegion } from "./types"; import { SharedAssetBundler } from "./shared-asset-bundler"; import { NagSuppressions } from "cdk-nag"; @@ -30,6 +30,7 @@ export class Shared extends Construct { readonly commonLayer: lambda.ILayerVersion; readonly powerToolsLayer: lambda.ILayerVersion; readonly sharedCode: SharedAssetBundler; + readonly s3vpcEndpoint: ec2.InterfaceVpcEndpoint; constructor(scope: Construct, id: string, props: SharedProps) { super(scope, id); @@ -90,6 +91,8 @@ export class Shared extends Construct { privateDnsEnabled: true, open: true, }); + + this.s3vpcEndpoint = s3vpcEndpoint; s3vpcEndpoint.node.addDependency(s3GatewayEndpoint); @@ -109,6 +112,86 @@ export class Shared extends Construct { service: ec2.InterfaceVpcEndpointAwsService.SAGEMAKER_RUNTIME, open: true, }); + + } + + if (props.config.privateWebsite) { + // Create VPC Endpoint for AppSync + vpc.addInterfaceEndpoint("AppSyncEndpoint", { + service: ec2.InterfaceVpcEndpointAwsService.APP_SYNC, + }); + + // Create VPC Endpoint for Lambda + vpc.addInterfaceEndpoint("LambdaEndpoint", { + service: ec2.InterfaceVpcEndpointAwsService.LAMBDA, + }); + + // Create VPC Endpoint for SNS + vpc.addInterfaceEndpoint("SNSEndpoint", { + service: ec2.InterfaceVpcEndpointAwsService.SNS, + }); + + // Create VPC Endpoint for Step Functions + vpc.addInterfaceEndpoint("StepFunctionsEndpoint", { + service: ec2.InterfaceVpcEndpointAwsService.STEP_FUNCTIONS, + }); + + // Create VPC Endpoint for SSM + vpc.addInterfaceEndpoint("SSMEndpoint", { + service: ec2.InterfaceVpcEndpointAwsService.SSM, + }); + + // Create VPC Endpoint for KMS + vpc.addInterfaceEndpoint("KMSEndpoint", { + service: ec2.InterfaceVpcEndpointAwsService.KMS, + }); + + // Create VPC Endpoint for Bedrock + if (props.config.bedrock?.enabled && Object.values(SupportedBedrockRegion).some(val => val === cdk.Stack.of(this).region)){ + vpc.addInterfaceEndpoint("BedrockEndpoint", { + service: new ec2.InterfaceVpcEndpointService('com.amazonaws.'+cdk.Aws.REGION+'.bedrock-runtime', 443), + privateDnsEnabled: true + }); + } + + // Create VPC Endpoint for Kendra + if (props.config.rag.engines.kendra.enabled){ + vpc.addInterfaceEndpoint("KendraEndpoint", { + service: ec2.InterfaceVpcEndpointAwsService.KENDRA, + }); + } + + // Create VPC Endpoint for RDS/Aurora + if (props.config.rag.engines.aurora.enabled) { + vpc.addInterfaceEndpoint("RDSEndpoint", { + service: ec2.InterfaceVpcEndpointAwsService.RDS, + }); + + // Create VPC Endpoint for RDS Data + vpc.addInterfaceEndpoint("RDSDataEndpoint", { + service: ec2.InterfaceVpcEndpointAwsService.RDS_DATA, + }); + } + + // Create VPC Endpoints needed for Aurora & Opensearch Indexing + if (props.config.rag.engines.aurora.enabled || + props.config.rag.engines.opensearch.enabled) { + // Create VPC Endpoint for ECS + vpc.addInterfaceEndpoint("ECSEndpoint", { + service: ec2.InterfaceVpcEndpointAwsService.ECS, + }); + + // Create VPC Endpoint for Batch + vpc.addInterfaceEndpoint("BatchEndpoint", { + service: ec2.InterfaceVpcEndpointAwsService.BATCH, + }); + + // Create VPC Endpoint for EC2 + vpc.addInterfaceEndpoint("EC2Endpoint", { + service: ec2.InterfaceVpcEndpointAwsService.EC2, + }); + } + } const configParameter = new ssm.StringParameter(this, "Config", { diff --git a/lib/shared/types.ts b/lib/shared/types.ts index cec3f44c0..5269c1294 100644 --- a/lib/shared/types.ts +++ b/lib/shared/types.ts @@ -42,6 +42,14 @@ export enum SupportedRegion { US_WEST_1 = "us-west-1", US_WEST_2 = "us-west-2", } + +export enum SupportedBedrockRegion { + AP_NORTHEAST_1 = "ap-northeast-1", + AP_SOUTHEAST_1 = "ap-southeast-1", + EU_CENTRAL_1 = "eu-central-1", + US_EAST_1 = "us-east-1", + US_WEST_2 = "us-west-2", +} export enum ModelInterface { LangChain = "langchain", @@ -65,6 +73,9 @@ export interface SystemConfig { vpcId?: string; createVpcEndpoints?: boolean; }; + certificate?: string; + domain?: string; + privateWebsite?: boolean; bedrock?: { enabled?: boolean; region?: SupportedRegion; diff --git a/lib/user-interface/index.ts b/lib/user-interface/index.ts index ff688c6b1..0cc25347d 100644 --- a/lib/user-interface/index.ts +++ b/lib/user-interface/index.ts @@ -14,6 +14,8 @@ import { Shared } from "../shared"; import { SystemConfig } from "../shared/types"; import { Utils } from "../shared/utils"; import { ChatBotApi } from "../chatbot-api"; +import { PrivateWebsite } from "./private-website" +import { PublicWebsite } from "./public-website" import { NagSuppressions } from "cdk-nag"; export interface UserInterfaceProps { @@ -46,83 +48,26 @@ export class UserInterface extends Construct { removalPolicy: cdk.RemovalPolicy.DESTROY, blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, autoDeleteObjects: true, + bucketName: props.config.privateWebsite ? props.config.domain : undefined, websiteIndexDocument: "index.html", websiteErrorDocument: "index.html", enforceSSL: true, serverAccessLogsBucket: uploadLogsBucket, }); - - const originAccessIdentity = new cf.OriginAccessIdentity(this, "S3OAI"); - websiteBucket.grantRead(originAccessIdentity); - props.chatbotFilesBucket.grantRead(originAccessIdentity); - - const distributionLogsBucket = new s3.Bucket( - this, - "DistributionLogsBucket", - { - objectOwnership: s3.ObjectOwnership.OBJECT_WRITER, - blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, - removalPolicy: cdk.RemovalPolicy.DESTROY, - autoDeleteObjects: true, - enforceSSL: true, - } - ); - - const distribution = new cf.CloudFrontWebDistribution( - this, - "Distribution", - { - viewerProtocolPolicy: cf.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, - priceClass: cf.PriceClass.PRICE_CLASS_ALL, - httpVersion: cf.HttpVersion.HTTP2_AND_3, - loggingConfig: { - bucket: distributionLogsBucket, - }, - originConfigs: [ - { - behaviors: [{ isDefaultBehavior: true }], - s3OriginSource: { - s3BucketSource: websiteBucket, - originAccessIdentity, - }, - }, - { - behaviors: [ - { - pathPattern: "/chabot/files/*", - allowedMethods: cf.CloudFrontAllowedMethods.ALL, - viewerProtocolPolicy: cf.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, - defaultTtl: cdk.Duration.seconds(0), - forwardedValues: { - queryString: true, - headers: [ - "Referer", - "Origin", - "Authorization", - "Content-Type", - "x-forwarded-user", - "Access-Control-Request-Headers", - "Access-Control-Request-Method", - ], - }, - }, - ], - s3OriginSource: { - s3BucketSource: props.chatbotFilesBucket, - originAccessIdentity, - }, - }, - ], - errorConfigurations: [ - { - errorCode: 404, - errorCachingMinTtl: 0, - responseCode: 200, - responsePagePath: "/index.html", - }, - ], - } - ); + + // Deploy either Private (only accessible within VPC) or Public facing website + let apiEndpoint: string; + let websocketEndpoint: string; + let distribution; + + if (props.config.privateWebsite) { + const privateWebsite = new PrivateWebsite(this, "PrivateWebsite", {...props, websiteBucket: websiteBucket }); + } else { + const publicWebsite = new PublicWebsite(this, "PublicWebsite", {...props, websiteBucket: websiteBucket }); + distribution = publicWebsite.distribution + } + + const exportsAsset = s3deploy.Source.jsonData("aws-exports.json", { aws_project_region: cdk.Aws.REGION, @@ -252,21 +197,15 @@ export class UserInterface extends Construct { prune: false, sources: [asset, exportsAsset], destinationBucket: websiteBucket, - distribution, - }); - - // ################################################### - // Outputs - // ################################################### - new cdk.CfnOutput(this, "UserInterfaceDomainName", { - value: `https://${distribution.distributionDomainName}`, + distribution: props.config.privateWebsite ? undefined : distribution }); + /** * CDK NAG suppression */ NagSuppressions.addResourceSuppressions( - [uploadLogsBucket, distributionLogsBucket], + uploadLogsBucket, [ { id: "AwsSolutions-S1", @@ -274,16 +213,5 @@ export class UserInterface extends Construct { }, ] ); - NagSuppressions.addResourceSuppressions(websiteBucket, [ - { id: "AwsSolutions-S5", reason: "OAI is configured for read." }, - ]); - NagSuppressions.addResourceSuppressions(distribution, [ - { id: "AwsSolutions-CFR1", reason: "No geo restrictions" }, - { - id: "AwsSolutions-CFR2", - reason: "WAF not required due to configured Cognito auth.", - }, - { id: "AwsSolutions-CFR4", reason: "TLS 1.2 is the default." }, - ]); } } diff --git a/lib/user-interface/private-website.ts b/lib/user-interface/private-website.ts new file mode 100644 index 000000000..0e30b4b06 --- /dev/null +++ b/lib/user-interface/private-website.ts @@ -0,0 +1,257 @@ +import * as apigwv2 from "@aws-cdk/aws-apigatewayv2-alpha"; +import * as cognitoIdentityPool from "@aws-cdk/aws-cognito-identitypool-alpha"; +import * as cdk from "aws-cdk-lib"; +import * as apigateway from "aws-cdk-lib/aws-apigateway"; +import * as cf from "aws-cdk-lib/aws-cloudfront"; +import * as iam from "aws-cdk-lib/aws-iam"; +import * as s3 from "aws-cdk-lib/aws-s3"; +import * as s3deploy from "aws-cdk-lib/aws-s3-deployment"; +import * as elbv2 from "aws-cdk-lib/aws-elasticloadbalancingv2"; +import * as ec2 from "aws-cdk-lib/aws-ec2"; +import * as route53 from "aws-cdk-lib/aws-route53"; +import { AwsCustomResource, AwsSdkCall, PhysicalResourceId } from "aws-cdk-lib/custom-resources"; +import { IpTarget } from "aws-cdk-lib/aws-elasticloadbalancingv2-targets"; +import { Construct } from "constructs"; +import { + ExecSyncOptionsWithBufferEncoding, + execSync, +} from "node:child_process"; +import * as path from "node:path"; +import { Shared } from "../shared"; +import { SystemConfig } from "../shared/types"; +import { Utils } from "../shared/utils"; +import { ChatBotApi } from "../chatbot-api"; +import { NagSuppressions } from "cdk-nag"; + + +export interface PrivateWebsiteProps { + readonly config: SystemConfig; + readonly shared: Shared; + readonly userPoolId: string; + readonly userPoolClientId: string; + readonly identityPool: cognitoIdentityPool.IdentityPool; + readonly api: ChatBotApi; + readonly chatbotFilesBucket: s3.Bucket; + readonly crossEncodersEnabled: boolean; + readonly sagemakerEmbeddingsEnabled: boolean; + readonly websiteBucket: s3.Bucket; +} + +export class PrivateWebsite extends Construct { + constructor(scope: Construct, id: string, props: PrivateWebsiteProps) { + super(scope, id); + + // PRIVATE WEBSITE + // REQUIRES: + // 1. ACM Certificate ARN and Domain of website to be input during 'npm run create': + // "privateWebsite" : true, + // "certificate" : "arn:aws:acm:ap-southeast-2:1234567890:certificate/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX", + // "domain" : "sub.example.com" + // 2. In Route 53 link the VPC to the Private Hosted Zone (PHZ) (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zone-private-associate-vpcs.html) + // 3. In the PHZ, add an "A Record" that points to the Application Load Balancer Alias (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-elb-load-balancer.html) + + // Retrieving S3 Endpoint Ips for ALB Target + const s3EndpointId = props.shared.s3vpcEndpoint.vpcEndpointId + const vpc = props.shared.vpc + const vpcEndpointNetworkInterfaceIds = props.shared.s3vpcEndpoint.vpcEndpointNetworkInterfaceIds + + // First, retrieve the VPC Endpoint + const vpcEndpointsCall: AwsSdkCall = { + service: 'EC2', + action: 'describeVpcEndpoints', + parameters: { + VpcEndpointIds: [s3EndpointId] + }, + physicalResourceId: cdk.custom_resources.PhysicalResourceId.of('describeNetworkInterfaces'), //PhysicalResourceId.of('describeVpcEndpoints'), + outputPaths: ['VpcEndpoints.0.NetworkInterfaceIds'] + } + + const vpcEndpoints = new AwsCustomResource( + this, 'describeVpcEndpoints', { + onCreate: vpcEndpointsCall, + onUpdate: vpcEndpointsCall, + policy: { + statements: [ + new iam.PolicyStatement({ + actions: ["ec2:DescribeVpcEndpoints"], + resources: ["*"] + })] + } + }) + + // Then, retrieve the Private IP Addresses for each ENI of the VPC Endpoint + let s3IPs: IpTarget[] = []; + for (let index = 0; index < vpc.availabilityZones.length; index++) { + + const eniId = cdk.Fn.select(index, vpcEndpointNetworkInterfaceIds) + + const sdkCall: AwsSdkCall = { + service: 'EC2', + action: 'describeNetworkInterfaces', + outputPaths: [`NetworkInterfaces.0.PrivateIpAddress`], + parameters: { + NetworkInterfaceIds: [vpcEndpoints.getResponseField(`VpcEndpoints.0.NetworkInterfaceIds.${index}`)], + Filters: [ + { Name: "interface-type", Values: ["vpc_endpoint"] } + ], + }, + physicalResourceId: cdk.custom_resources.PhysicalResourceId.of('describeNetworkInterfaces'), //PhysicalResourceId.of('describeNetworkInterfaces'), + } + + const eni = new AwsCustomResource( + this, + `DescribeNetworkInterfaces-${index}`, + { + onCreate: sdkCall, + onUpdate: sdkCall, + policy: { + statements: [ + new iam.PolicyStatement({ + actions: ["ec2:DescribeNetworkInterfaces"], + resources: ["*"] //[`arn:aws:ec2:${process.env.CDK_DEFAULT_REGION }:${process.env.CDK_DEFAULT_ACCOUNT}:network-interface/${eniId}`] + }), + ], + }, + } + ); + + s3IPs.push(new IpTarget(cdk.Token.asString(eni.getResponseField(`NetworkInterfaces.0.PrivateIpAddress`)), 443)) + } + + + // Website ALB + const albSecurityGroup = new ec2.SecurityGroup(this, 'WebsiteApplicationLoadBalancerSG', { + vpc: props.shared.vpc, + allowAllOutbound: false + }); + + albSecurityGroup.addIngressRule( + ec2.Peer.anyIpv4(), + ec2.Port.tcp(443) + ); + + albSecurityGroup.addIngressRule( + ec2.Peer.anyIpv4(), + ec2.Port.tcp(80) + ); + + albSecurityGroup.addEgressRule( + ec2.Peer.ipv4(props.shared.vpc.vpcCidrBlock), + ec2.Port.tcp(443) + ); + + const loadBalancer = new elbv2.ApplicationLoadBalancer(this, 'ALB', { + vpc: props.shared.vpc, + internetFacing: false, + securityGroup: albSecurityGroup, + vpcSubnets: props.shared.vpc.selectSubnets({ + subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS + }), + }); + + const albLogBucket = new s3.Bucket(this, 'ALBLoggingBucket', { + + blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, + removalPolicy: cdk.RemovalPolicy.DESTROY, + autoDeleteObjects: true, + enforceSSL: true, + + }); + loadBalancer.logAccessLogs(albLogBucket) + + // Adding Listener + // Using ACM certificate ARN passed in through props/config file + if (props.config.certificate) { + const albListener = loadBalancer.addListener('ALBLHTTPS', + { + protocol: elbv2.ApplicationProtocol.HTTPS, + port: 443, + certificates: [elbv2.ListenerCertificate.fromArn(props.config.certificate)], + sslPolicy: elbv2.SslPolicy.RECOMMENDED_TLS + }); + + // Add ALB targets + albListener.addTargets('s3TargetGroup', + { + port: 443, + protocol: elbv2.ApplicationProtocol.HTTPS, + targets: s3IPs, + healthCheck: { + protocol: elbv2.Protocol.HTTPS, + path: '/', + healthyHttpCodes: '307,405' + } + }); + + // The Amazon S3 PrivateLink Endpoint is a REST API Endpoint, which means that trailing slash requests will return XML directory listings by default. + // To work around this, you’ll create a redirect rule to point all requests ending in a trailing slash to index.html. + albListener.addAction('privateLinkRedirectPath', { + priority: 1, + conditions: [ + elbv2.ListenerCondition.pathPatterns(['/']), + ], + action: elbv2.ListenerAction.redirect({ + port: '#{port}', + path: '/index.html', //'/#{path}index.html' // + }) + }); + } + + // Allow access to website bucket from S3 Endpoints + props.websiteBucket.policy?.document.addStatements( + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + actions: ['s3:GetObject', "s3:List*"], + principals: [new iam.AnyPrincipal()], + resources: [props.websiteBucket.bucketArn, `${props.websiteBucket.bucketArn}/*`], + conditions: { + "StringEquals": { "aws:SourceVpce": s3EndpointId } + } + }) + ); + + // ################################################### + // Outputs + // ################################################### + new cdk.CfnOutput(this, "Domain", { + value: `https://${props.config.domain}`, + }); + + new cdk.CfnOutput(this, "LoadBalancerDNS", { + value: loadBalancer.loadBalancerDnsName, + }); + + NagSuppressions.addResourceSuppressions( + albSecurityGroup, + [ + { + id: "AwsSolutions-EC23", + reason: "Website Application Load Balancer can be open to 0.0.0.0/0 on ports 80 & 443.", + }, + ] + ); + + NagSuppressions.addResourceSuppressions( + props.websiteBucket, + [ + { + id: "AwsSolutions-S5", + reason: "Bucket has conditions to only allow access from S3 VPC Endpoints.", + }, + ] + ); + + NagSuppressions.addResourceSuppressions( + albLogBucket, + [ + { + id: "AwsSolutions-S1", + reason: "Bucket is the server access logs bucket for ALB.", + }, + ] + ); + + + + } +} \ No newline at end of file diff --git a/lib/user-interface/public-website.ts b/lib/user-interface/public-website.ts new file mode 100644 index 000000000..0e4682155 --- /dev/null +++ b/lib/user-interface/public-website.ts @@ -0,0 +1,155 @@ +import * as apigwv2 from "@aws-cdk/aws-apigatewayv2-alpha"; +import * as cognitoIdentityPool from "@aws-cdk/aws-cognito-identitypool-alpha"; +import * as cdk from "aws-cdk-lib"; +import * as apigateway from "aws-cdk-lib/aws-apigateway"; +import * as cf from "aws-cdk-lib/aws-cloudfront"; +import * as iam from "aws-cdk-lib/aws-iam"; +import * as s3 from "aws-cdk-lib/aws-s3"; +import * as s3deploy from "aws-cdk-lib/aws-s3-deployment"; +import * as elbv2 from "aws-cdk-lib/aws-elasticloadbalancingv2"; +import * as ec2 from "aws-cdk-lib/aws-ec2"; +import * as route53 from "aws-cdk-lib/aws-route53"; +import { IpTarget } from "aws-cdk-lib/aws-elasticloadbalancingv2-targets"; +import { Construct } from "constructs"; +import { + ExecSyncOptionsWithBufferEncoding, + execSync, +} from "node:child_process"; +import * as path from "node:path"; +import { Shared } from "../shared"; +import { SystemConfig } from "../shared/types"; +import { Utils } from "../shared/utils"; +import { ChatBotApi } from "../chatbot-api"; +import { NagSuppressions } from "cdk-nag"; + + +export interface PublicWebsiteProps { + readonly config: SystemConfig; + readonly shared: Shared; + readonly userPoolId: string; + readonly userPoolClientId: string; + readonly identityPool: cognitoIdentityPool.IdentityPool; + readonly api: ChatBotApi; + readonly chatbotFilesBucket: s3.Bucket; + readonly crossEncodersEnabled: boolean; + readonly sagemakerEmbeddingsEnabled: boolean; + readonly websiteBucket: s3.Bucket; +} + +export class PublicWebsite extends Construct { + readonly distribution: cf.CloudFrontWebDistribution; + + constructor(scope: Construct, id: string, props: PublicWebsiteProps) { + super(scope, id); + + ///////////////////////////////////// + ///// CLOUDFRONT IMPLEMENTATION ///// + ///////////////////////////////////// + + const originAccessIdentity = new cf.OriginAccessIdentity(this, "S3OAI"); + props.websiteBucket.grantRead(originAccessIdentity); + props.chatbotFilesBucket.grantRead(originAccessIdentity); + + + const distributionLogsBucket = new s3.Bucket( + this, + "DistributionLogsBucket", + { + objectOwnership: s3.ObjectOwnership.OBJECT_WRITER, + blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, + removalPolicy: cdk.RemovalPolicy.DESTROY, + autoDeleteObjects: true, + enforceSSL: true, + } + ); + + const distribution = new cf.CloudFrontWebDistribution( + this, + "Distribution", + { + viewerProtocolPolicy: cf.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, + priceClass: cf.PriceClass.PRICE_CLASS_ALL, + httpVersion: cf.HttpVersion.HTTP2_AND_3, + loggingConfig: { + bucket: distributionLogsBucket, + }, + originConfigs: [ + { + behaviors: [{ isDefaultBehavior: true }], + s3OriginSource: { + s3BucketSource: props.websiteBucket, + originAccessIdentity, + }, + }, + { + behaviors: [ + { + pathPattern: "/chabot/files/*", + allowedMethods: cf.CloudFrontAllowedMethods.ALL, + viewerProtocolPolicy: cf.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, + defaultTtl: cdk.Duration.seconds(0), + forwardedValues: { + queryString: true, + headers: [ + "Referer", + "Origin", + "Authorization", + "Content-Type", + "x-forwarded-user", + "Access-Control-Request-Headers", + "Access-Control-Request-Method", + ], + }, + }, + ], + s3OriginSource: { + s3BucketSource: props.chatbotFilesBucket, + originAccessIdentity, + }, + }, + ], + errorConfigurations: [ + { + errorCode: 404, + errorCachingMinTtl: 0, + responseCode: 200, + responsePagePath: "/index.html", + }, + ], + } + ); + + this.distribution = distribution; + + // ################################################### + // Outputs + // ################################################### + new cdk.CfnOutput(this, "UserInterfaceDomainName", { + value: `https://${distribution.distributionDomainName}`, + }); + + NagSuppressions.addResourceSuppressions( + distributionLogsBucket, + [ + { + id: "AwsSolutions-S1", + reason: "Bucket is the server access logs bucket for websiteBucket.", + }, + ] + ); + + NagSuppressions.addResourceSuppressions(props.websiteBucket, [ + { id: "AwsSolutions-S5", reason: "OAI is configured for read." }, + ]); + + NagSuppressions.addResourceSuppressions(distribution, [ + { id: "AwsSolutions-CFR1", reason: "No geo restrictions" }, + { + id: "AwsSolutions-CFR2", + reason: "WAF not required due to configured Cognito auth.", + }, + { id: "AwsSolutions-CFR4", reason: "TLS 1.2 is the default." }, + ]); + } + + } diff --git a/lib/user-interface/react-app/src/app.tsx b/lib/user-interface/react-app/src/app.tsx index 0fb4b3992..3933c4081 100644 --- a/lib/user-interface/react-app/src/app.tsx +++ b/lib/user-interface/react-app/src/app.tsx @@ -1,4 +1,4 @@ -import { BrowserRouter, Routes, Route, Outlet } from "react-router-dom"; +import { HashRouter, BrowserRouter, Routes, Route, Outlet } from "react-router-dom"; import GlobalHeader from "./components/global-header"; import Dashboard from "./pages/rag/dashboard/dashboard"; import NotFound from "./pages/not-found"; @@ -16,11 +16,14 @@ import AddData from "./pages/rag/add-data/add-data"; import "./styles/app.scss"; import MultiChatPlayground from "./pages/chatbot/playground/multi-chat-playground"; import RssFeed from "./pages/rag/workspace/rss-feed"; +import * as InfraConfig from '../../../../bin/config.json'; function App() { + const Router = InfraConfig.privateWebsite ? HashRouter : BrowserRouter; + return (

- +
 
@@ -53,7 +56,7 @@ function App() { } />
-
+
); } diff --git a/lib/user-interface/react-app/src/components/app-configured.tsx b/lib/user-interface/react-app/src/components/app-configured.tsx index 01d09484d..636819a06 100644 --- a/lib/user-interface/react-app/src/components/app-configured.tsx +++ b/lib/user-interface/react-app/src/components/app-configured.tsx @@ -156,7 +156,7 @@ export default function AppConfigured() { }, }} > - + From 20828628f83fca299cf3775deb62014a4957dbac Mon Sep 17 00:00:00 2001 From: Rob-Powell <7034920+Rob-Powell@users.noreply.github.com> Date: Tue, 30 Jan 2024 07:00:27 +0000 Subject: [PATCH 09/23] feat: removing auto generated files from git and generating them in npm build command --- .gitignore | 6 + lib/user-interface/react-app/src/API.ts | 971 ------------------ .../react-app/src/graphql/mutations.ts | 247 ----- .../react-app/src/graphql/queries.ts | 398 ------- .../react-app/src/graphql/subscriptions.ts | 22 - package.json | 2 +- 6 files changed, 7 insertions(+), 1639 deletions(-) delete mode 100644 lib/user-interface/react-app/src/API.ts delete mode 100644 lib/user-interface/react-app/src/graphql/mutations.ts delete mode 100644 lib/user-interface/react-app/src/graphql/queries.ts delete mode 100644 lib/user-interface/react-app/src/graphql/subscriptions.ts diff --git a/.gitignore b/.gitignore index fa75e92da..7c085fd51 100644 --- a/.gitignore +++ b/.gitignore @@ -447,3 +447,9 @@ bin/config.json docs/.vitepress/cache docs/.vitepress/dist lib/user-interface/react-app/.graphqlconfig.yml + +# Amplify auto-generated files +lib/user-interface/react-app/src/API.ts +lib/user-interface/react-app/src/graphql/mutations.ts +lib/user-interface/react-app/src/graphql/queries.ts +lib/user-interface/react-app/src/graphql/subscriptions.ts diff --git a/lib/user-interface/react-app/src/API.ts b/lib/user-interface/react-app/src/API.ts deleted file mode 100644 index c19dd1516..000000000 --- a/lib/user-interface/react-app/src/API.ts +++ /dev/null @@ -1,971 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -// This file was automatically generated and should not be edited. - -export type CreateWorkspaceKendraInput = { - name: string, - kind: string, - kendraIndexId: string, - useAllData: boolean, -}; - -export type Workspace = { - __typename: "Workspace", - id: string, - name: string, - formatVersion?: number | null, - engine: string, - status?: string | null, - aossEngine?: string | null, - languages?: Array< string | null > | null, - hasIndex?: boolean | null, - embeddingsModelProvider?: string | null, - embeddingsModelName?: string | null, - embeddingsModelDimensions?: number | null, - crossEncoderModelName?: string | null, - crossEncoderModelProvider?: string | null, - metric?: string | null, - index?: boolean | null, - hybridSearch?: boolean | null, - chunkingStrategy?: string | null, - chunkSize?: number | null, - chunkOverlap?: number | null, - vectors?: number | null, - documents?: number | null, - sizeInBytes?: number | null, - kendraIndexId?: string | null, - kendraIndexExternal?: boolean | null, - kendraUseAllData?: boolean | null, - createdAt: string, - updatedAt: string, -}; - -export type CreateWorkspaceOpenSearchInput = { - name: string, - kind: string, - embeddingsModelProvider: string, - embeddingsModelName: string, - crossEncoderModelProvider: string, - crossEncoderModelName: string, - languages: Array< string >, - hybridSearch: boolean, - chunkingStrategy: string, - chunkSize: number, - chunkOverlap: number, -}; - -export type CreateWorkspaceAuroraInput = { - name: string, - kind: string, - embeddingsModelProvider: string, - embeddingsModelName: string, - crossEncoderModelProvider: string, - crossEncoderModelName: string, - languages: Array< string >, - metric: string, - index: boolean, - hybridSearch: boolean, - chunkingStrategy: string, - chunkSize: number, - chunkOverlap: number, -}; - -export type TextDocumentInput = { - workspaceId: string, - title: string, - content: string, -}; - -export type DocumentResult = { - __typename: "DocumentResult", - workspaceId: string, - documentId: string, - status?: string | null, -}; - -export type QnADocumentInput = { - workspaceId: string, - question: string, - answer: string, -}; - -export type DocumentSubscriptionStatusInput = { - workspaceId: string, - documentId: string, - status: string, -}; - -export type WebsiteInput = { - workspaceId: string, - sitemap: boolean, - address: string, - followLinks: boolean, - limit: number, -}; - -export type RssFeedInput = { - workspaceId: string, - address: string, - limit: number, - title?: string | null, - followLinks: boolean, -}; - -export type DeleteSessionResult = { - __typename: "DeleteSessionResult", - id?: string | null, - deleted: boolean, -}; - -export type Channel = { - __typename: "Channel", - data?: string | null, - sessionId?: string | null, - userId?: string | null, -}; - -export type FileUploadInput = { - workspaceId: string, - fileName: string, -}; - -export type FileUploadResult = { - __typename: "FileUploadResult", - url: string, - fields?: string | null, -}; - -export type Model = { - __typename: "Model", - name: string, - provider: string, - interface: string, - ragSupported: boolean, - inputModalities: Array< string >, - outputModalities: Array< string >, - streaming: boolean, -}; - -export type RagEngine = { - __typename: "RagEngine", - id: string, - name: string, - enabled: boolean, -}; - -export type SemanticSearchInput = { - workspaceId: string, - query: string, -}; - -export type SemanticSearchResult = { - __typename: "SemanticSearchResult", - engine: string, - workspaceId: string, - queryLanguage?: string | null, - supportedLanguages?: Array< string > | null, - detectedLanguages?: Array | null, - items?: Array | null, - vectorSearchMetric?: string | null, - vectorSearchItems?: Array | null, - keywordSearchItems?: Array | null, -}; - -export type DetectedLanguage = { - __typename: "DetectedLanguage", - code: string, - score: number, -}; - -export type SemanticSearchItem = { - __typename: "SemanticSearchItem", - sources?: Array< string | null > | null, - chunkId?: string | null, - workspaceId: string, - documentId?: string | null, - documentSubId?: string | null, - documentSubType?: string | null, - documentType: string, - path?: string | null, - language?: string | null, - title?: string | null, - content?: string | null, - contentComplement?: string | null, - vectorSearchScore?: number | null, - keywordSearchScore?: number | null, - score?: number | null, -}; - -export type Session = { - __typename: "Session", - id: string, - title?: string | null, - startTime: string, - history?: Array | null, -}; - -export type SessionHistoryItem = { - __typename: "SessionHistoryItem", - type: string, - content: string, - metadata?: string | null, -}; - -export type EmbeddingModel = { - __typename: "EmbeddingModel", - provider: string, - name: string, - dimensions: number, - default?: boolean | null, -}; - -export type CalculateEmbeddingsInput = { - provider: string, - model: string, - passages: Array< string | null >, -}; - -export type Embedding = { - __typename: "Embedding", - passage?: string | null, - vector: Array< number >, -}; - -export type KendraIndex = { - __typename: "KendraIndex", - id: string, - name: string, - external: boolean, -}; - -export type ListDocumentsInput = { - workspaceId: string, - documentType: string, - lastDocumentId?: string | null, -}; - -export type DocumentsResult = { - __typename: "DocumentsResult", - items: Array, - lastDocumentId?: string | null, -}; - -export type Document = { - __typename: "Document", - workspaceId: string, - id: string, - type: string, - subType?: string | null, - status?: string | null, - title?: string | null, - path?: string | null, - sizeInBytes?: number | null, - vectors?: number | null, - subDocuments?: number | null, - crawlerProperties?: CrawlerProperties | null, - errors?: Array< string > | null, - createdAt: string, - updatedAt?: string | null, - rssFeedId?: string | null, - rssLastCheckedAt?: string | null, -}; - -export type CrawlerProperties = { - __typename: "CrawlerProperties", - followLinks?: boolean | null, - limit?: number | null, -}; - -export type GetDocumentInput = { - workspaceId: string, - documentId: string, -}; - -export type GetRSSPostsInput = { - workspaceId: string, - documentId: string, - lastDocumentId?: string | null, -}; - -export type CrossEncoderData = { - __typename: "CrossEncoderData", - provider: string, - name: string, - default: boolean, -}; - -export type RankPassagesInput = { - provider: string, - model: string, - reference: string, - passages: Array< string | null >, -}; - -export type PassageRank = { - __typename: "PassageRank", - score: number, - passage: string, -}; - -export type CreateKendraWorkspaceMutationVariables = { - input: CreateWorkspaceKendraInput, -}; - -export type CreateKendraWorkspaceMutation = { - createKendraWorkspace: { - __typename: "Workspace", - id: string, - name: string, - formatVersion?: number | null, - engine: string, - status?: string | null, - aossEngine?: string | null, - languages?: Array< string | null > | null, - hasIndex?: boolean | null, - embeddingsModelProvider?: string | null, - embeddingsModelName?: string | null, - embeddingsModelDimensions?: number | null, - crossEncoderModelName?: string | null, - crossEncoderModelProvider?: string | null, - metric?: string | null, - index?: boolean | null, - hybridSearch?: boolean | null, - chunkingStrategy?: string | null, - chunkSize?: number | null, - chunkOverlap?: number | null, - vectors?: number | null, - documents?: number | null, - sizeInBytes?: number | null, - kendraIndexId?: string | null, - kendraIndexExternal?: boolean | null, - kendraUseAllData?: boolean | null, - createdAt: string, - updatedAt: string, - }, -}; - -export type CreateOpenSearchWorkspaceMutationVariables = { - input: CreateWorkspaceOpenSearchInput, -}; - -export type CreateOpenSearchWorkspaceMutation = { - createOpenSearchWorkspace: { - __typename: "Workspace", - id: string, - name: string, - formatVersion?: number | null, - engine: string, - status?: string | null, - aossEngine?: string | null, - languages?: Array< string | null > | null, - hasIndex?: boolean | null, - embeddingsModelProvider?: string | null, - embeddingsModelName?: string | null, - embeddingsModelDimensions?: number | null, - crossEncoderModelName?: string | null, - crossEncoderModelProvider?: string | null, - metric?: string | null, - index?: boolean | null, - hybridSearch?: boolean | null, - chunkingStrategy?: string | null, - chunkSize?: number | null, - chunkOverlap?: number | null, - vectors?: number | null, - documents?: number | null, - sizeInBytes?: number | null, - kendraIndexId?: string | null, - kendraIndexExternal?: boolean | null, - kendraUseAllData?: boolean | null, - createdAt: string, - updatedAt: string, - }, -}; - -export type CreateAuroraWorkspaceMutationVariables = { - input: CreateWorkspaceAuroraInput, -}; - -export type CreateAuroraWorkspaceMutation = { - createAuroraWorkspace: { - __typename: "Workspace", - id: string, - name: string, - formatVersion?: number | null, - engine: string, - status?: string | null, - aossEngine?: string | null, - languages?: Array< string | null > | null, - hasIndex?: boolean | null, - embeddingsModelProvider?: string | null, - embeddingsModelName?: string | null, - embeddingsModelDimensions?: number | null, - crossEncoderModelName?: string | null, - crossEncoderModelProvider?: string | null, - metric?: string | null, - index?: boolean | null, - hybridSearch?: boolean | null, - chunkingStrategy?: string | null, - chunkSize?: number | null, - chunkOverlap?: number | null, - vectors?: number | null, - documents?: number | null, - sizeInBytes?: number | null, - kendraIndexId?: string | null, - kendraIndexExternal?: boolean | null, - kendraUseAllData?: boolean | null, - createdAt: string, - updatedAt: string, - }, -}; - -export type StartKendraDataSyncMutationVariables = { - workspaceId: string, -}; - -export type StartKendraDataSyncMutation = { - startKendraDataSync?: boolean | null, -}; - -export type DeleteWorkspaceMutationVariables = { - workspaceId: string, -}; - -export type DeleteWorkspaceMutation = { - deleteWorkspace?: boolean | null, -}; - -export type AddTextDocumentMutationVariables = { - input: TextDocumentInput, -}; - -export type AddTextDocumentMutation = { - addTextDocument?: { - __typename: "DocumentResult", - workspaceId: string, - documentId: string, - status?: string | null, - } | null, -}; - -export type AddQnADocumentMutationVariables = { - input: QnADocumentInput, -}; - -export type AddQnADocumentMutation = { - addQnADocument?: { - __typename: "DocumentResult", - workspaceId: string, - documentId: string, - status?: string | null, - } | null, -}; - -export type SetDocumentSubscriptionStatusMutationVariables = { - input: DocumentSubscriptionStatusInput, -}; - -export type SetDocumentSubscriptionStatusMutation = { - setDocumentSubscriptionStatus?: { - __typename: "DocumentResult", - workspaceId: string, - documentId: string, - status?: string | null, - } | null, -}; - -export type AddWebsiteMutationVariables = { - input: WebsiteInput, -}; - -export type AddWebsiteMutation = { - addWebsite?: { - __typename: "DocumentResult", - workspaceId: string, - documentId: string, - status?: string | null, - } | null, -}; - -export type AddRssFeedMutationVariables = { - input: RssFeedInput, -}; - -export type AddRssFeedMutation = { - addRssFeed?: { - __typename: "DocumentResult", - workspaceId: string, - documentId: string, - status?: string | null, - } | null, -}; - -export type UpdateRssFeedMutationVariables = { - input: RssFeedInput, -}; - -export type UpdateRssFeedMutation = { - updateRssFeed?: { - __typename: "DocumentResult", - workspaceId: string, - documentId: string, - status?: string | null, - } | null, -}; - -export type DeleteUserSessionsMutationVariables = { -}; - -export type DeleteUserSessionsMutation = { - deleteUserSessions?: Array< { - __typename: "DeleteSessionResult", - id?: string | null, - deleted: boolean, - } > | null, -}; - -export type DeleteSessionMutationVariables = { - id: string, -}; - -export type DeleteSessionMutation = { - deleteSession?: { - __typename: "DeleteSessionResult", - id?: string | null, - deleted: boolean, - } | null, -}; - -export type SendQueryMutationVariables = { - data?: string | null, -}; - -export type SendQueryMutation = { - // Real-time - sendQuery?: string | null, -}; - -export type PublishResponseMutationVariables = { - sessionId?: string | null, - userId?: string | null, - data?: string | null, -}; - -export type PublishResponseMutation = { - publishResponse?: { - __typename: "Channel", - data?: string | null, - sessionId?: string | null, - userId?: string | null, - } | null, -}; - -export type CheckHealthQueryVariables = { -}; - -export type CheckHealthQuery = { - checkHealth?: boolean | null, -}; - -export type GetUploadFileURLQueryVariables = { - input: FileUploadInput, -}; - -export type GetUploadFileURLQuery = { - getUploadFileURL?: { - __typename: "FileUploadResult", - url: string, - fields?: string | null, - } | null, -}; - -export type ListModelsQueryVariables = { -}; - -export type ListModelsQuery = { - listModels: Array< { - __typename: "Model", - name: string, - provider: string, - interface: string, - ragSupported: boolean, - inputModalities: Array< string >, - outputModalities: Array< string >, - streaming: boolean, - } >, -}; - -export type ListWorkspacesQueryVariables = { -}; - -export type ListWorkspacesQuery = { - listWorkspaces: Array< { - __typename: "Workspace", - id: string, - name: string, - formatVersion?: number | null, - engine: string, - status?: string | null, - aossEngine?: string | null, - languages?: Array< string | null > | null, - hasIndex?: boolean | null, - embeddingsModelProvider?: string | null, - embeddingsModelName?: string | null, - embeddingsModelDimensions?: number | null, - crossEncoderModelName?: string | null, - crossEncoderModelProvider?: string | null, - metric?: string | null, - index?: boolean | null, - hybridSearch?: boolean | null, - chunkingStrategy?: string | null, - chunkSize?: number | null, - chunkOverlap?: number | null, - vectors?: number | null, - documents?: number | null, - sizeInBytes?: number | null, - kendraIndexId?: string | null, - kendraIndexExternal?: boolean | null, - kendraUseAllData?: boolean | null, - createdAt: string, - updatedAt: string, - } >, -}; - -export type GetWorkspaceQueryVariables = { - workspaceId: string, -}; - -export type GetWorkspaceQuery = { - getWorkspace?: { - __typename: "Workspace", - id: string, - name: string, - formatVersion?: number | null, - engine: string, - status?: string | null, - aossEngine?: string | null, - languages?: Array< string | null > | null, - hasIndex?: boolean | null, - embeddingsModelProvider?: string | null, - embeddingsModelName?: string | null, - embeddingsModelDimensions?: number | null, - crossEncoderModelName?: string | null, - crossEncoderModelProvider?: string | null, - metric?: string | null, - index?: boolean | null, - hybridSearch?: boolean | null, - chunkingStrategy?: string | null, - chunkSize?: number | null, - chunkOverlap?: number | null, - vectors?: number | null, - documents?: number | null, - sizeInBytes?: number | null, - kendraIndexId?: string | null, - kendraIndexExternal?: boolean | null, - kendraUseAllData?: boolean | null, - createdAt: string, - updatedAt: string, - } | null, -}; - -export type ListRagEnginesQueryVariables = { -}; - -export type ListRagEnginesQuery = { - listRagEngines: Array< { - __typename: "RagEngine", - id: string, - name: string, - enabled: boolean, - } >, -}; - -export type PerformSemanticSearchQueryVariables = { - input: SemanticSearchInput, -}; - -export type PerformSemanticSearchQuery = { - performSemanticSearch: { - __typename: "SemanticSearchResult", - engine: string, - workspaceId: string, - queryLanguage?: string | null, - supportedLanguages?: Array< string > | null, - detectedLanguages?: Array< { - __typename: "DetectedLanguage", - code: string, - score: number, - } > | null, - items?: Array< { - __typename: "SemanticSearchItem", - sources?: Array< string | null > | null, - chunkId?: string | null, - workspaceId: string, - documentId?: string | null, - documentSubId?: string | null, - documentSubType?: string | null, - documentType: string, - path?: string | null, - language?: string | null, - title?: string | null, - content?: string | null, - contentComplement?: string | null, - vectorSearchScore?: number | null, - keywordSearchScore?: number | null, - score?: number | null, - } > | null, - vectorSearchMetric?: string | null, - vectorSearchItems?: Array< { - __typename: "SemanticSearchItem", - sources?: Array< string | null > | null, - chunkId?: string | null, - workspaceId: string, - documentId?: string | null, - documentSubId?: string | null, - documentSubType?: string | null, - documentType: string, - path?: string | null, - language?: string | null, - title?: string | null, - content?: string | null, - contentComplement?: string | null, - vectorSearchScore?: number | null, - keywordSearchScore?: number | null, - score?: number | null, - } > | null, - keywordSearchItems?: Array< { - __typename: "SemanticSearchItem", - sources?: Array< string | null > | null, - chunkId?: string | null, - workspaceId: string, - documentId?: string | null, - documentSubId?: string | null, - documentSubType?: string | null, - documentType: string, - path?: string | null, - language?: string | null, - title?: string | null, - content?: string | null, - contentComplement?: string | null, - vectorSearchScore?: number | null, - keywordSearchScore?: number | null, - score?: number | null, - } > | null, - }, -}; - -export type ListSessionsQueryVariables = { -}; - -export type ListSessionsQuery = { - listSessions: Array< { - __typename: "Session", - id: string, - title?: string | null, - startTime: string, - history?: Array< { - __typename: "SessionHistoryItem", - type: string, - content: string, - metadata?: string | null, - } | null > | null, - } >, -}; - -export type ListEmbeddingModelsQueryVariables = { -}; - -export type ListEmbeddingModelsQuery = { - listEmbeddingModels: Array< { - __typename: "EmbeddingModel", - provider: string, - name: string, - dimensions: number, - default?: boolean | null, - } >, -}; - -export type CalculateEmbeddingsQueryVariables = { - input: CalculateEmbeddingsInput, -}; - -export type CalculateEmbeddingsQuery = { - calculateEmbeddings: Array< { - __typename: "Embedding", - passage?: string | null, - vector: Array< number >, - } | null >, -}; - -export type GetSessionQueryVariables = { - id: string, -}; - -export type GetSessionQuery = { - getSession?: { - __typename: "Session", - id: string, - title?: string | null, - startTime: string, - history?: Array< { - __typename: "SessionHistoryItem", - type: string, - content: string, - metadata?: string | null, - } | null > | null, - } | null, -}; - -export type ListKendraIndexesQueryVariables = { -}; - -export type ListKendraIndexesQuery = { - listKendraIndexes: Array< { - __typename: "KendraIndex", - id: string, - name: string, - external: boolean, - } >, -}; - -export type IsKendraDataSynchingQueryVariables = { - workspaceId: string, -}; - -export type IsKendraDataSynchingQuery = { - isKendraDataSynching?: boolean | null, -}; - -export type ListDocumentsQueryVariables = { - input: ListDocumentsInput, -}; - -export type ListDocumentsQuery = { - listDocuments: { - __typename: "DocumentsResult", - items: Array< { - __typename: "Document", - workspaceId: string, - id: string, - type: string, - subType?: string | null, - status?: string | null, - title?: string | null, - path?: string | null, - sizeInBytes?: number | null, - vectors?: number | null, - subDocuments?: number | null, - crawlerProperties?: { - __typename: "CrawlerProperties", - followLinks?: boolean | null, - limit?: number | null, - } | null, - errors?: Array< string > | null, - createdAt: string, - updatedAt?: string | null, - rssFeedId?: string | null, - rssLastCheckedAt?: string | null, - } | null >, - lastDocumentId?: string | null, - }, -}; - -export type GetDocumentQueryVariables = { - input: GetDocumentInput, -}; - -export type GetDocumentQuery = { - getDocument?: { - __typename: "Document", - workspaceId: string, - id: string, - type: string, - subType?: string | null, - status?: string | null, - title?: string | null, - path?: string | null, - sizeInBytes?: number | null, - vectors?: number | null, - subDocuments?: number | null, - crawlerProperties?: { - __typename: "CrawlerProperties", - followLinks?: boolean | null, - limit?: number | null, - } | null, - errors?: Array< string > | null, - createdAt: string, - updatedAt?: string | null, - rssFeedId?: string | null, - rssLastCheckedAt?: string | null, - } | null, -}; - -export type GetRSSPostsQueryVariables = { - input: GetRSSPostsInput, -}; - -export type GetRSSPostsQuery = { - getRSSPosts?: { - __typename: "DocumentsResult", - items: Array< { - __typename: "Document", - workspaceId: string, - id: string, - type: string, - subType?: string | null, - status?: string | null, - title?: string | null, - path?: string | null, - sizeInBytes?: number | null, - vectors?: number | null, - subDocuments?: number | null, - crawlerProperties?: { - __typename: "CrawlerProperties", - followLinks?: boolean | null, - limit?: number | null, - } | null, - errors?: Array< string > | null, - createdAt: string, - updatedAt?: string | null, - rssFeedId?: string | null, - rssLastCheckedAt?: string | null, - } | null >, - lastDocumentId?: string | null, - } | null, -}; - -export type ListCrossEncodersQueryVariables = { -}; - -export type ListCrossEncodersQuery = { - listCrossEncoders?: Array< { - __typename: "CrossEncoderData", - provider: string, - name: string, - default: boolean, - } > | null, -}; - -export type RankPassagesQueryVariables = { - input: RankPassagesInput, -}; - -export type RankPassagesQuery = { - rankPassages: Array< { - __typename: "PassageRank", - score: number, - passage: string, - } >, -}; - -export type ReceiveMessagesSubscriptionVariables = { - sessionId?: string | null, -}; - -export type ReceiveMessagesSubscription = { - receiveMessages?: { - __typename: "Channel", - data?: string | null, - sessionId?: string | null, - userId?: string | null, - } | null, -}; diff --git a/lib/user-interface/react-app/src/graphql/mutations.ts b/lib/user-interface/react-app/src/graphql/mutations.ts deleted file mode 100644 index 5d93e490d..000000000 --- a/lib/user-interface/react-app/src/graphql/mutations.ts +++ /dev/null @@ -1,247 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -// this is an auto generated file. This will be overwritten - -import * as APITypes from "../API"; -type GeneratedMutation = string & { - __generatedMutationInput: InputType; - __generatedMutationOutput: OutputType; -}; - -export const createKendraWorkspace = /* GraphQL */ `mutation CreateKendraWorkspace($input: CreateWorkspaceKendraInput!) { - createKendraWorkspace(input: $input) { - id - name - formatVersion - engine - status - aossEngine - languages - hasIndex - embeddingsModelProvider - embeddingsModelName - embeddingsModelDimensions - crossEncoderModelName - crossEncoderModelProvider - metric - index - hybridSearch - chunkingStrategy - chunkSize - chunkOverlap - vectors - documents - sizeInBytes - kendraIndexId - kendraIndexExternal - kendraUseAllData - createdAt - updatedAt - __typename - } -} -` as GeneratedMutation< - APITypes.CreateKendraWorkspaceMutationVariables, - APITypes.CreateKendraWorkspaceMutation ->; -export const createOpenSearchWorkspace = /* GraphQL */ `mutation CreateOpenSearchWorkspace($input: CreateWorkspaceOpenSearchInput!) { - createOpenSearchWorkspace(input: $input) { - id - name - formatVersion - engine - status - aossEngine - languages - hasIndex - embeddingsModelProvider - embeddingsModelName - embeddingsModelDimensions - crossEncoderModelName - crossEncoderModelProvider - metric - index - hybridSearch - chunkingStrategy - chunkSize - chunkOverlap - vectors - documents - sizeInBytes - kendraIndexId - kendraIndexExternal - kendraUseAllData - createdAt - updatedAt - __typename - } -} -` as GeneratedMutation< - APITypes.CreateOpenSearchWorkspaceMutationVariables, - APITypes.CreateOpenSearchWorkspaceMutation ->; -export const createAuroraWorkspace = /* GraphQL */ `mutation CreateAuroraWorkspace($input: CreateWorkspaceAuroraInput!) { - createAuroraWorkspace(input: $input) { - id - name - formatVersion - engine - status - aossEngine - languages - hasIndex - embeddingsModelProvider - embeddingsModelName - embeddingsModelDimensions - crossEncoderModelName - crossEncoderModelProvider - metric - index - hybridSearch - chunkingStrategy - chunkSize - chunkOverlap - vectors - documents - sizeInBytes - kendraIndexId - kendraIndexExternal - kendraUseAllData - createdAt - updatedAt - __typename - } -} -` as GeneratedMutation< - APITypes.CreateAuroraWorkspaceMutationVariables, - APITypes.CreateAuroraWorkspaceMutation ->; -export const startKendraDataSync = /* GraphQL */ `mutation StartKendraDataSync($workspaceId: String!) { - startKendraDataSync(workspaceId: $workspaceId) -} -` as GeneratedMutation< - APITypes.StartKendraDataSyncMutationVariables, - APITypes.StartKendraDataSyncMutation ->; -export const deleteWorkspace = /* GraphQL */ `mutation DeleteWorkspace($workspaceId: String!) { - deleteWorkspace(workspaceId: $workspaceId) -} -` as GeneratedMutation< - APITypes.DeleteWorkspaceMutationVariables, - APITypes.DeleteWorkspaceMutation ->; -export const addTextDocument = /* GraphQL */ `mutation AddTextDocument($input: TextDocumentInput!) { - addTextDocument(input: $input) { - workspaceId - documentId - status - __typename - } -} -` as GeneratedMutation< - APITypes.AddTextDocumentMutationVariables, - APITypes.AddTextDocumentMutation ->; -export const addQnADocument = /* GraphQL */ `mutation AddQnADocument($input: QnADocumentInput!) { - addQnADocument(input: $input) { - workspaceId - documentId - status - __typename - } -} -` as GeneratedMutation< - APITypes.AddQnADocumentMutationVariables, - APITypes.AddQnADocumentMutation ->; -export const setDocumentSubscriptionStatus = /* GraphQL */ `mutation SetDocumentSubscriptionStatus( - $input: DocumentSubscriptionStatusInput! -) { - setDocumentSubscriptionStatus(input: $input) { - workspaceId - documentId - status - __typename - } -} -` as GeneratedMutation< - APITypes.SetDocumentSubscriptionStatusMutationVariables, - APITypes.SetDocumentSubscriptionStatusMutation ->; -export const addWebsite = /* GraphQL */ `mutation AddWebsite($input: WebsiteInput!) { - addWebsite(input: $input) { - workspaceId - documentId - status - __typename - } -} -` as GeneratedMutation< - APITypes.AddWebsiteMutationVariables, - APITypes.AddWebsiteMutation ->; -export const addRssFeed = /* GraphQL */ `mutation AddRssFeed($input: RssFeedInput!) { - addRssFeed(input: $input) { - workspaceId - documentId - status - __typename - } -} -` as GeneratedMutation< - APITypes.AddRssFeedMutationVariables, - APITypes.AddRssFeedMutation ->; -export const updateRssFeed = /* GraphQL */ `mutation UpdateRssFeed($input: RssFeedInput!) { - updateRssFeed(input: $input) { - workspaceId - documentId - status - __typename - } -} -` as GeneratedMutation< - APITypes.UpdateRssFeedMutationVariables, - APITypes.UpdateRssFeedMutation ->; -export const deleteUserSessions = /* GraphQL */ `mutation DeleteUserSessions { - deleteUserSessions { - id - deleted - __typename - } -} -` as GeneratedMutation< - APITypes.DeleteUserSessionsMutationVariables, - APITypes.DeleteUserSessionsMutation ->; -export const deleteSession = /* GraphQL */ `mutation DeleteSession($id: String!) { - deleteSession(id: $id) { - id - deleted - __typename - } -} -` as GeneratedMutation< - APITypes.DeleteSessionMutationVariables, - APITypes.DeleteSessionMutation ->; -export const sendQuery = /* GraphQL */ `mutation SendQuery($data: String) { - sendQuery(data: $data) -} -` as GeneratedMutation< - APITypes.SendQueryMutationVariables, - APITypes.SendQueryMutation ->; -export const publishResponse = /* GraphQL */ `mutation PublishResponse($sessionId: String, $userId: String, $data: String) { - publishResponse(sessionId: $sessionId, userId: $userId, data: $data) { - data - sessionId - userId - __typename - } -} -` as GeneratedMutation< - APITypes.PublishResponseMutationVariables, - APITypes.PublishResponseMutation ->; diff --git a/lib/user-interface/react-app/src/graphql/queries.ts b/lib/user-interface/react-app/src/graphql/queries.ts deleted file mode 100644 index 0eff5181e..000000000 --- a/lib/user-interface/react-app/src/graphql/queries.ts +++ /dev/null @@ -1,398 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -// this is an auto generated file. This will be overwritten - -import * as APITypes from "../API"; -type GeneratedQuery = string & { - __generatedQueryInput: InputType; - __generatedQueryOutput: OutputType; -}; - -export const checkHealth = /* GraphQL */ `query CheckHealth { - checkHealth -} -` as GeneratedQuery< - APITypes.CheckHealthQueryVariables, - APITypes.CheckHealthQuery ->; -export const getUploadFileURL = /* GraphQL */ `query GetUploadFileURL($input: FileUploadInput!) { - getUploadFileURL(input: $input) { - url - fields - __typename - } -} -` as GeneratedQuery< - APITypes.GetUploadFileURLQueryVariables, - APITypes.GetUploadFileURLQuery ->; -export const listModels = /* GraphQL */ `query ListModels { - listModels { - name - provider - interface - ragSupported - inputModalities - outputModalities - streaming - __typename - } -} -` as GeneratedQuery< - APITypes.ListModelsQueryVariables, - APITypes.ListModelsQuery ->; -export const listWorkspaces = /* GraphQL */ `query ListWorkspaces { - listWorkspaces { - id - name - formatVersion - engine - status - aossEngine - languages - hasIndex - embeddingsModelProvider - embeddingsModelName - embeddingsModelDimensions - crossEncoderModelName - crossEncoderModelProvider - metric - index - hybridSearch - chunkingStrategy - chunkSize - chunkOverlap - vectors - documents - sizeInBytes - kendraIndexId - kendraIndexExternal - kendraUseAllData - createdAt - updatedAt - __typename - } -} -` as GeneratedQuery< - APITypes.ListWorkspacesQueryVariables, - APITypes.ListWorkspacesQuery ->; -export const getWorkspace = /* GraphQL */ `query GetWorkspace($workspaceId: String!) { - getWorkspace(workspaceId: $workspaceId) { - id - name - formatVersion - engine - status - aossEngine - languages - hasIndex - embeddingsModelProvider - embeddingsModelName - embeddingsModelDimensions - crossEncoderModelName - crossEncoderModelProvider - metric - index - hybridSearch - chunkingStrategy - chunkSize - chunkOverlap - vectors - documents - sizeInBytes - kendraIndexId - kendraIndexExternal - kendraUseAllData - createdAt - updatedAt - __typename - } -} -` as GeneratedQuery< - APITypes.GetWorkspaceQueryVariables, - APITypes.GetWorkspaceQuery ->; -export const listRagEngines = /* GraphQL */ `query ListRagEngines { - listRagEngines { - id - name - enabled - __typename - } -} -` as GeneratedQuery< - APITypes.ListRagEnginesQueryVariables, - APITypes.ListRagEnginesQuery ->; -export const performSemanticSearch = /* GraphQL */ `query PerformSemanticSearch($input: SemanticSearchInput!) { - performSemanticSearch(input: $input) { - engine - workspaceId - queryLanguage - supportedLanguages - detectedLanguages { - code - score - __typename - } - items { - sources - chunkId - workspaceId - documentId - documentSubId - documentSubType - documentType - path - language - title - content - contentComplement - vectorSearchScore - keywordSearchScore - score - __typename - } - vectorSearchMetric - vectorSearchItems { - sources - chunkId - workspaceId - documentId - documentSubId - documentSubType - documentType - path - language - title - content - contentComplement - vectorSearchScore - keywordSearchScore - score - __typename - } - keywordSearchItems { - sources - chunkId - workspaceId - documentId - documentSubId - documentSubType - documentType - path - language - title - content - contentComplement - vectorSearchScore - keywordSearchScore - score - __typename - } - __typename - } -} -` as GeneratedQuery< - APITypes.PerformSemanticSearchQueryVariables, - APITypes.PerformSemanticSearchQuery ->; -export const listSessions = /* GraphQL */ `query ListSessions { - listSessions { - id - title - startTime - history { - type - content - metadata - __typename - } - __typename - } -} -` as GeneratedQuery< - APITypes.ListSessionsQueryVariables, - APITypes.ListSessionsQuery ->; -export const listEmbeddingModels = /* GraphQL */ `query ListEmbeddingModels { - listEmbeddingModels { - provider - name - dimensions - default - __typename - } -} -` as GeneratedQuery< - APITypes.ListEmbeddingModelsQueryVariables, - APITypes.ListEmbeddingModelsQuery ->; -export const calculateEmbeddings = /* GraphQL */ `query CalculateEmbeddings($input: CalculateEmbeddingsInput!) { - calculateEmbeddings(input: $input) { - passage - vector - __typename - } -} -` as GeneratedQuery< - APITypes.CalculateEmbeddingsQueryVariables, - APITypes.CalculateEmbeddingsQuery ->; -export const getSession = /* GraphQL */ `query GetSession($id: String!) { - getSession(id: $id) { - id - title - startTime - history { - type - content - metadata - __typename - } - __typename - } -} -` as GeneratedQuery< - APITypes.GetSessionQueryVariables, - APITypes.GetSessionQuery ->; -export const listKendraIndexes = /* GraphQL */ `query ListKendraIndexes { - listKendraIndexes { - id - name - external - __typename - } -} -` as GeneratedQuery< - APITypes.ListKendraIndexesQueryVariables, - APITypes.ListKendraIndexesQuery ->; -export const isKendraDataSynching = /* GraphQL */ `query IsKendraDataSynching($workspaceId: String!) { - isKendraDataSynching(workspaceId: $workspaceId) -} -` as GeneratedQuery< - APITypes.IsKendraDataSynchingQueryVariables, - APITypes.IsKendraDataSynchingQuery ->; -export const listDocuments = /* GraphQL */ `query ListDocuments($input: ListDocumentsInput!) { - listDocuments(input: $input) { - items { - workspaceId - id - type - subType - status - title - path - sizeInBytes - vectors - subDocuments - crawlerProperties { - followLinks - limit - __typename - } - errors - createdAt - updatedAt - rssFeedId - rssLastCheckedAt - __typename - } - lastDocumentId - __typename - } -} -` as GeneratedQuery< - APITypes.ListDocumentsQueryVariables, - APITypes.ListDocumentsQuery ->; -export const getDocument = /* GraphQL */ `query GetDocument($input: GetDocumentInput!) { - getDocument(input: $input) { - workspaceId - id - type - subType - status - title - path - sizeInBytes - vectors - subDocuments - crawlerProperties { - followLinks - limit - __typename - } - errors - createdAt - updatedAt - rssFeedId - rssLastCheckedAt - __typename - } -} -` as GeneratedQuery< - APITypes.GetDocumentQueryVariables, - APITypes.GetDocumentQuery ->; -export const getRSSPosts = /* GraphQL */ `query GetRSSPosts($input: GetRSSPostsInput!) { - getRSSPosts(input: $input) { - items { - workspaceId - id - type - subType - status - title - path - sizeInBytes - vectors - subDocuments - crawlerProperties { - followLinks - limit - __typename - } - errors - createdAt - updatedAt - rssFeedId - rssLastCheckedAt - __typename - } - lastDocumentId - __typename - } -} -` as GeneratedQuery< - APITypes.GetRSSPostsQueryVariables, - APITypes.GetRSSPostsQuery ->; -export const listCrossEncoders = /* GraphQL */ `query ListCrossEncoders { - listCrossEncoders { - provider - name - default - __typename - } -} -` as GeneratedQuery< - APITypes.ListCrossEncodersQueryVariables, - APITypes.ListCrossEncodersQuery ->; -export const rankPassages = /* GraphQL */ `query RankPassages($input: RankPassagesInput!) { - rankPassages(input: $input) { - score - passage - __typename - } -} -` as GeneratedQuery< - APITypes.RankPassagesQueryVariables, - APITypes.RankPassagesQuery ->; diff --git a/lib/user-interface/react-app/src/graphql/subscriptions.ts b/lib/user-interface/react-app/src/graphql/subscriptions.ts deleted file mode 100644 index 7160163af..000000000 --- a/lib/user-interface/react-app/src/graphql/subscriptions.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -// this is an auto generated file. This will be overwritten - -import * as APITypes from "../API"; -type GeneratedSubscription = string & { - __generatedSubscriptionInput: InputType; - __generatedSubscriptionOutput: OutputType; -}; - -export const receiveMessages = /* GraphQL */ `subscription ReceiveMessages($sessionId: String) { - receiveMessages(sessionId: $sessionId) { - data - sessionId - userId - __typename - } -} -` as GeneratedSubscription< - APITypes.ReceiveMessagesSubscriptionVariables, - APITypes.ReceiveMessagesSubscription ->; diff --git a/package.json b/package.json index 47c45c060..d255cc2a4 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "aws-genai-llm-chatbot": "bin/aws-genai-llm-chatbot.js" }, "scripts": { - "build": "tsc", + "build": "npx @aws-amplify/cli codegen && tsc", "watch": "tsc -w", "cdk": "cdk", "gen": "npx @aws-amplify/cli codegen", From 957dccc0efc171392bc2828c4bed583870abb2a6 Mon Sep 17 00:00:00 2001 From: Massimiliano Angelino Date: Wed, 31 Jan 2024 10:12:22 +0100 Subject: [PATCH 10/23] fix(magic create): removed console.log and reordered options --- cli/magic-create.ts | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/cli/magic-create.ts b/cli/magic-create.ts index 671ec8059..c78671254 100644 --- a/cli/magic-create.ts +++ b/cli/magic-create.ts @@ -9,7 +9,7 @@ import { SupportedRegion, SupportedSageMakerModels, SystemConfig, - SupportedBedrockRegion + SupportedBedrockRegion, } from "../lib/shared/types"; import { LIB_VERSION } from "./version.js"; import * as fs from "fs"; @@ -120,17 +120,15 @@ async function processCreateOptions(options: any): Promise { { type: "confirm", name: "privateWebsite", - message: "Do you want to deploy a private website? I.e only accessible in VPC", - initial: - options.privateWebsite || - false, + message: + "Do you want to deploy a private website? I.e only accessible in VPC", + initial: options.privateWebsite || false, }, { type: "input", name: "certificate", message: "ACM certificate ARN", - initial: - options.certificate, + initial: options.certificate, skip(): boolean { return !(this as any).state.answers.privateWebsite; }, @@ -139,8 +137,7 @@ async function processCreateOptions(options: any): Promise { type: "input", name: "domain", message: "Domain for private website", - initial: - options.domain, + initial: options.domain, skip(): boolean { return !(this as any).state.answers.privateWebsite; }, @@ -223,6 +220,15 @@ async function processCreateOptions(options: any): Promise { }, initial: options.ragsToEnable || [], }, + { + type: "confirm", + name: "kendraEnterprise", + message: "Do you want to enable Kendra Enterprise Edition?", + initial: options.kendraEnterprise || false, + skip(): boolean { + return !(this as any).state.answers.ragsToEnable.includes("kendra"); + }, + }, { type: "confirm", name: "kendra", @@ -235,18 +241,8 @@ async function processCreateOptions(options: any): Promise { return !(this as any).state.answers.enableRag; }, }, - { - type: "confirm", - name: "kendraEnterprise", - message: "Do you want to enable Kendra Enterprise Edition?", - initial: options.kendraEnterprise || false, - skip(): boolean { - return !(this as any).state.answers.ragsToEnable.includes("kendra"); - }, - }, ]; const answers: any = await enquirer.prompt(questions); - console.log(answers); const kendraExternal = []; let newKendra = answers.enableRag && answers.kendra; const existingKendraIndices = Array.from(options.kendraExternal || []); From 2ceb1e4cbf6144b66a481569d03019aad7a71c37 Mon Sep 17 00:00:00 2001 From: Daniel Moser Date: Thu, 1 Feb 2024 15:22:37 +0100 Subject: [PATCH 11/23] Fix #344. Dynamically create cdk-nag suppression based on AZ number --- lib/aws-genai-llm-chatbot-stack.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/aws-genai-llm-chatbot-stack.ts b/lib/aws-genai-llm-chatbot-stack.ts index 589fa0906..3d6e8dbb9 100644 --- a/lib/aws-genai-llm-chatbot-stack.ts +++ b/lib/aws-genai-llm-chatbot-stack.ts @@ -417,21 +417,21 @@ export class AwsGenAILLMChatbotStack extends cdk.Stack { ]); if (props.config.privateWebsite) { + const paths = []; + for(let index = 0; index < shared.vpc.availabilityZones.length; index++) { + paths.push(`/${this.stackName}/UserInterface/PrivateWebsite/DescribeNetworkInterfaces-${index}/CustomResourcePolicy/Resource`,) + } + paths.push(`/${this.stackName}/UserInterface/PrivateWebsite/describeVpcEndpoints/CustomResourcePolicy/Resource`,) NagSuppressions.addResourceSuppressionsByPath( - this, - [ - `/${this.stackName}/UserInterface/PrivateWebsite/DescribeNetworkInterfaces-0/CustomResourcePolicy/Resource`, - `/${this.stackName}/UserInterface/PrivateWebsite/DescribeNetworkInterfaces-1/CustomResourcePolicy/Resource`, - `/${this.stackName}/UserInterface/PrivateWebsite/DescribeNetworkInterfaces-2/CustomResourcePolicy/Resource`, - `/${this.stackName}/UserInterface/PrivateWebsite/describeVpcEndpoints/CustomResourcePolicy/Resource`, - ], - [ - { - id: "AwsSolutions-IAM5", - reason: - "Custom Resource requires permissions to Describe VPC Endpoint Network Interfaces", - }, - ] + this, + paths, + [ + { + id: "AwsSolutions-IAM5", + reason: + "Custom Resource requires permissions to Describe VPC Endpoint Network Interfaces", + }, + ] ); NagSuppressions.addResourceSuppressionsByPath( this, From 254bbc344501914045576871c81cd134b6810545 Mon Sep 17 00:00:00 2001 From: Bigad Soleiman Date: Thu, 1 Feb 2024 14:44:41 +0000 Subject: [PATCH 12/23] Update README.md --- README.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a7be84535..648333f31 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,8 @@ Supported model providers: - [Bigad Soleiman](https://www.linkedin.com/in/bigadsoleiman/) - [Sergey Pugachev](https://www.linkedin.com/in/spugachev/) -# Credits - -This sample was made possible thanks to the following libraries: - -- [langchain](https://python.langchain.com/docs/get_started/introduction.html) from [LangChain AI](https://github.com/langchain-ai) -- [unstructured](https://github.com/Unstructured-IO/unstructured) from [Unstructured-IO](https://github.com/Unstructured-IO/unstructured) -- [pgvector](https://github.com/pgvector/pgvector) from [Andrew Kane](https://github.com/ankane) +# Contributors +[![contributors](https://contrib.rocks/image?repo=aws-samples/aws-genai-llm-chatbot&max=2000)](https://github.com/aws-samples/aws-genai-llm-chatbot/graphs/contributors) # License From 415e6e03eedba770862c1153b9810bcbbf61b486 Mon Sep 17 00:00:00 2001 From: Alain Krok Date: Wed, 31 Jan 2024 17:45:48 -0600 Subject: [PATCH 13/23] chore(deps): use gen ai cdk constructs for sagemaker model deployment --- lib/models/index.ts | 361 +++++++++++++++++++++++--------------------- package-lock.json | 37 ++++- package.json | 3 +- 3 files changed, 222 insertions(+), 179 deletions(-) diff --git a/lib/models/index.ts b/lib/models/index.ts index 986efeace..79a861c06 100644 --- a/lib/models/index.ts +++ b/lib/models/index.ts @@ -1,11 +1,7 @@ import * as cdk from "aws-cdk-lib"; import * as ssm from "aws-cdk-lib/aws-ssm"; import { Construct } from "constructs"; -import { - ContainerImages, - DeploymentType, - SageMakerModel, -} from "../sagemaker-model"; +import * as iam from 'aws-cdk-lib/aws-iam'; import { Shared } from "../shared"; import { Modality, @@ -14,6 +10,14 @@ import { SupportedSageMakerModels, SystemConfig, } from "../shared/types"; +import { + HuggingFaceSageMakerEndpoint, + JumpStartSageMakerEndpoint, + SageMakerInstanceType, + DeepLearningContainerImage, + JumpStartModel +} from '@cdklabs/generative-ai-cdk-constructs'; +import { NagSuppressions } from "cdk-nag"; export interface ModelsProps { readonly config: SystemConfig; @@ -32,34 +36,39 @@ export class Models extends Construct { if ( props.config.llms?.sagemaker.includes(SupportedSageMakerModels.FalconLite) ) { - const falconLite = new SageMakerModel(this, "FalconLite", { - vpc: props.shared.vpc, - region: cdk.Aws.REGION, - model: { - type: DeploymentType.Container, - modelId: "amazon/FalconLite", - container: ContainerImages.HF_PYTORCH_LLM_TGI_INFERENCE_0_9_3, - instanceType: "ml.g5.12xlarge", - // https://github.com/awslabs/extending-the-context-length-of-open-source-llms/blob/main/custom-tgi-ecr/deploy.ipynb - containerStartupHealthCheckTimeoutInSeconds: 600, - env: { - SM_NUM_GPUS: JSON.stringify(4), - MAX_INPUT_LENGTH: JSON.stringify(12000), - MAX_TOTAL_TOKENS: JSON.stringify(12001), - HF_MODEL_QUANTIZE: "gptq", - TRUST_REMOTE_CODE: JSON.stringify(true), - MAX_BATCH_PREFILL_TOKENS: JSON.stringify(12001), - MAX_BATCH_TOTAL_TOKENS: JSON.stringify(12001), - GPTQ_BITS: JSON.stringify(4), - GPTQ_GROUPSIZE: JSON.stringify(128), - DNTK_ALPHA_SCALER: JSON.stringify(0.25), - }, + + const FALCON_MODEL_ID = 'amazon/FalconLite'; + const FALCON_ENDPOINT_NAME = FALCON_MODEL_ID.split("/").join("-").split(".").join("-"); + + const falconLite = new HuggingFaceSageMakerEndpoint(this, 'FalconLite', { + modelId:FALCON_MODEL_ID, + vpcConfig: { + securityGroupIds: [props.shared.vpc.vpcDefaultSecurityGroup], + subnets: props.shared.vpc.privateSubnets.map((subnet) => subnet.subnetId), }, + container: DeepLearningContainerImage.HUGGINGFACE_PYTORCH_TGI_INFERENCE_2_0_1_TGI0_9_3_GPU_PY39_CU118_UBUNTU20_04, + instanceType: SageMakerInstanceType.ML_G5_12XLARGE, + startupHealthCheckTimeoutInSeconds: 600, + endpointName: FALCON_ENDPOINT_NAME, + environment: { + SM_NUM_GPUS: JSON.stringify(4), + MAX_INPUT_LENGTH: JSON.stringify(12000), + MAX_TOTAL_TOKENS: JSON.stringify(12001), + HF_MODEL_QUANTIZE: "gptq", + TRUST_REMOTE_CODE: JSON.stringify(true), + MAX_BATCH_PREFILL_TOKENS: JSON.stringify(12001), + MAX_BATCH_TOTAL_TOKENS: JSON.stringify(12001), + GPTQ_BITS: JSON.stringify(4), + GPTQ_GROUPSIZE: JSON.stringify(128), + DNTK_ALPHA_SCALER: JSON.stringify(0.25), + } }); + this.suppressCdkNagWarningForEndpointRole(falconLite.role); + models.push({ - name: falconLite.endpoint.endpointName!, - endpoint: falconLite.endpoint, + name: FALCON_ENDPOINT_NAME!, + endpoint: falconLite.cfnEndpoint, responseStreamingSupported: false, inputModalities: [Modality.Text], outputModalities: [Modality.Text], @@ -73,27 +82,32 @@ export class Models extends Construct { SupportedSageMakerModels.Mistral7b_Instruct ) ) { - const mistral7bInstruct = new SageMakerModel(this, "Mistral7BInstruct", { - vpc: props.shared.vpc, - region: cdk.Aws.REGION, - model: { - type: DeploymentType.Container, - modelId: "mistralai/Mistral-7B-Instruct-v0.1", - container: ContainerImages.HF_PYTORCH_LLM_TGI_INFERENCE_1_1_0, - instanceType: "ml.g5.2xlarge", - containerStartupHealthCheckTimeoutInSeconds: 300, - env: { - SM_NUM_GPUS: JSON.stringify(1), - MAX_INPUT_LENGTH: JSON.stringify(2048), - MAX_TOTAL_TOKENS: JSON.stringify(4096), - //HF_MODEL_QUANTIZE: "bitsandbytes", - }, + + const MISTRAL_7B_MODEL_ID = 'mistralai/Mistral-7B-Instruct-v0.1'; + const MISTRAL_7B_ENDPOINT_NAME = MISTRAL_7B_MODEL_ID.split("/").join("-").split(".").join("-"); + + const mistral7B = new HuggingFaceSageMakerEndpoint(this, 'Mistral7BInstruct', { + modelId:MISTRAL_7B_MODEL_ID, + vpcConfig: { + securityGroupIds: [props.shared.vpc.vpcDefaultSecurityGroup], + subnets: props.shared.vpc.privateSubnets.map((subnet) => subnet.subnetId), }, + container: DeepLearningContainerImage.HUGGINGFACE_PYTORCH_TGI_INFERENCE_2_0_1_TGI1_1_0_GPU_PY39_CU118_UBUNTU20_04, + instanceType: SageMakerInstanceType.ML_G5_2XLARGE, + startupHealthCheckTimeoutInSeconds: 300, + endpointName: MISTRAL_7B_ENDPOINT_NAME, + environment: { + SM_NUM_GPUS: JSON.stringify(1), + MAX_INPUT_LENGTH: JSON.stringify(2048), + MAX_TOTAL_TOKENS: JSON.stringify(4096), + } }); + this.suppressCdkNagWarningForEndpointRole(mistral7B.role); + models.push({ - name: mistral7bInstruct.endpoint.endpointName!, - endpoint: mistral7bInstruct.endpoint, + name: MISTRAL_7B_ENDPOINT_NAME!, + endpoint: mistral7B.cfnEndpoint, responseStreamingSupported: false, inputModalities: [Modality.Text], outputModalities: [Modality.Text], @@ -107,31 +121,33 @@ export class Models extends Construct { SupportedSageMakerModels.Mistral7b_Instruct2 ) ) { - const mistral7bInstruct2 = new SageMakerModel( - this, - "Mistral7BInstruct2", - { - vpc: props.shared.vpc, - region: cdk.Aws.REGION, - model: { - type: DeploymentType.Container, - modelId: "mistralai/Mistral-7B-Instruct-v0.2", - container: ContainerImages.HF_PYTORCH_LLM_TGI_INFERENCE_1_3_3, - instanceType: "ml.g5.2xlarge", - containerStartupHealthCheckTimeoutInSeconds: 300, - env: { - SM_NUM_GPUS: JSON.stringify(1), - MAX_INPUT_LENGTH: JSON.stringify(2048), - MAX_TOTAL_TOKENS: JSON.stringify(4096), - MAX_CONCURRENT_REQUESTS: JSON.stringify(4), - }, - }, - } - ); + + const MISTRAL_7B_INSTRUCT2_MODEL_ID = 'mistralai/Mistral-7B-Instruct-v0.2'; + const MISTRAL_7B_INSTRUCT2_ENDPOINT_NAME = MISTRAL_7B_INSTRUCT2_MODEL_ID.split("/").join("-").split(".").join("-"); + + const mistral7BInstruct2 = new HuggingFaceSageMakerEndpoint(this, 'Mistral7BInstruct2', { + modelId:MISTRAL_7B_INSTRUCT2_MODEL_ID, + vpcConfig: { + securityGroupIds: [props.shared.vpc.vpcDefaultSecurityGroup], + subnets: props.shared.vpc.privateSubnets.map((subnet) => subnet.subnetId), + }, + container: DeepLearningContainerImage.fromDeepLearningContainerImage('huggingface-pytorch-tgi-inference','2.1.1-tgi1.3.3-gpu-py310-cu121-ubuntu20.04'), + instanceType: SageMakerInstanceType.ML_G5_2XLARGE, + startupHealthCheckTimeoutInSeconds: 300, + endpointName: MISTRAL_7B_INSTRUCT2_ENDPOINT_NAME, + environment: { + SM_NUM_GPUS: JSON.stringify(1), + MAX_INPUT_LENGTH: JSON.stringify(2048), + MAX_TOTAL_TOKENS: JSON.stringify(4096), + MAX_CONCURRENT_REQUESTS: JSON.stringify(4), + }, + }); + + this.suppressCdkNagWarningForEndpointRole(mistral7BInstruct2.role); models.push({ - name: mistral7bInstruct2.endpoint.endpointName!, - endpoint: mistral7bInstruct2.endpoint, + name: MISTRAL_7B_INSTRUCT2_ENDPOINT_NAME!, + endpoint: mistral7BInstruct2.cfnEndpoint, responseStreamingSupported: false, inputModalities: [Modality.Text], outputModalities: [Modality.Text], @@ -145,32 +161,34 @@ export class Models extends Construct { SupportedSageMakerModels.Mixtral_8x7b_Instruct ) ) { - const mixtral8x7binstruct = new SageMakerModel( - this, - "Mixtral8x7binstruct", - { - vpc: props.shared.vpc, - region: cdk.Aws.REGION, - model: { - type: DeploymentType.Container, - modelId: "mistralai/Mixtral-8x7B-Instruct-v0.1", - container: ContainerImages.HF_PYTORCH_LLM_TGI_INFERENCE_1_3_3, - instanceType: "ml.g5.48xlarge", - containerStartupHealthCheckTimeoutInSeconds: 300, - env: { - SM_NUM_GPUS: JSON.stringify(8), - MAX_INPUT_LENGTH: JSON.stringify(24576), - MAX_TOTAL_TOKENS: JSON.stringify(32768), - MAX_BATCH_PREFILL_TOKENS: JSON.stringify(24576), - MAX_CONCURRENT_REQUESTS: JSON.stringify(4), - }, - }, - } - ); + + const MISTRAL_8x7B_MODEL_ID = 'mistralai/Mixtral-8x7B-Instruct-v0.1'; + const MISTRAL_8x7B_INSTRUCT2_ENDPOINT_NAME = MISTRAL_8x7B_MODEL_ID.split("/").join("-").split(".").join("-"); + + const mistral8x7B = new HuggingFaceSageMakerEndpoint(this, 'Mixtral8x7binstruct', { + modelId:MISTRAL_8x7B_MODEL_ID, + vpcConfig: { + securityGroupIds: [props.shared.vpc.vpcDefaultSecurityGroup], + subnets: props.shared.vpc.privateSubnets.map((subnet) => subnet.subnetId), + }, + container: DeepLearningContainerImage.fromDeepLearningContainerImage('huggingface-pytorch-tgi-inference','2.1.1-tgi1.3.3-gpu-py310-cu121-ubuntu20.04'), + instanceType: SageMakerInstanceType.ML_G5_48XLARGE, + startupHealthCheckTimeoutInSeconds: 300, + endpointName: MISTRAL_8x7B_INSTRUCT2_ENDPOINT_NAME, + environment: { + SM_NUM_GPUS: JSON.stringify(8), + MAX_INPUT_LENGTH: JSON.stringify(24576), + MAX_TOTAL_TOKENS: JSON.stringify(32768), + MAX_BATCH_PREFILL_TOKENS: JSON.stringify(24576), + MAX_CONCURRENT_REQUESTS: JSON.stringify(4), + }, + }); + + this.suppressCdkNagWarningForEndpointRole(mistral8x7B.role); models.push({ - name: mixtral8x7binstruct.endpoint.endpointName!, - endpoint: mixtral8x7binstruct.endpoint, + name: MISTRAL_8x7B_INSTRUCT2_ENDPOINT_NAME!, + endpoint: mistral8x7B.cfnEndpoint, responseStreamingSupported: false, inputModalities: [Modality.Text], outputModalities: [Modality.Text], @@ -178,57 +196,30 @@ export class Models extends Construct { ragSupported: true, }); } - // To get Jumpstart model ARNs do the following - // 1. Identify the modelId via https://sagemaker.readthedocs.io/en/stable/doc_utils/pretrainedmodels.html - // 2. Run the following code - // - // from sagemaker.jumpstart.model import JumpStartModel - // region = 'us-east-1' - // model_id = 'meta-textgeneration-llama-2-13b-f' - // model = JumpStartModel(model_id=model_id, region=region) - // print(model.model_package_arn) + if ( props.config.llms?.sagemaker.includes( SupportedSageMakerModels.Llama2_13b_Chat ) ) { - const llama2chat = new SageMakerModel(this, "LLamaV2_13B_Chat", { - vpc: props.shared.vpc, - region: cdk.Aws.REGION, - model: { - type: DeploymentType.ModelPackage, - modelId: "meta-LLama2-13b-chat", - instanceType: "ml.g5.12xlarge", - packages: (scope) => - new cdk.CfnMapping(scope, "Llama2ChatPackageMapping", { - lazy: true, - mapping: { - "ap-southeast-1": { - arn: `arn:aws:sagemaker:ap-southeast-1:192199979996:model-package/llama2-13b-f-v4-55c7c39a0cf535e8bad0d342598c219b`, - }, - "ap-southeast-2": { - arn: `arn:aws:sagemaker:ap-southeast-2:666831318237:model-package/llama2-13b-f-v4-55c7c39a0cf535e8bad0d342598c219b`, - }, - "eu-west-1": { - arn: `arn:aws:sagemaker:eu-west-1:985815980388:model-package/llama2-13b-f-v4-55c7c39a0cf535e8bad0d342598c219b`, - }, - "us-east-1": { - arn: `arn:aws:sagemaker:us-east-1:865070037744:model-package/llama2-13b-f-v4-55c7c39a0cf535e8bad0d342598c219b`, - }, - "us-east-2": { - arn: `arn:aws:sagemaker:us-east-2:057799348421:model-package/llama2-13b-f-v4-55c7c39a0cf535e8bad0d342598c219b`, - }, - "us-west-2": { - arn: `arn:aws:sagemaker:us-west-2:594846645681:model-package/llama2-13b-f-v4-55c7c39a0cf535e8bad0d342598c219b`, - }, - }, - }), + + const LLAMA2_13B_CHAT_ENDPOINT_NAME = "meta-LLama2-13b-chat"; + + const llama2_13b_chat = new JumpStartSageMakerEndpoint(this, 'LLamaV2_13B_Chat', { + model: JumpStartModel.META_TEXTGENERATION_LLAMA_2_13B_F_3_0_2, + instanceType: SageMakerInstanceType.ML_G5_12XLARGE, + vpcConfig: { + securityGroupIds: [props.shared.vpc.vpcDefaultSecurityGroup], + subnets: props.shared.vpc.privateSubnets.map((subnet) => subnet.subnetId), }, + endpointName: LLAMA2_13B_CHAT_ENDPOINT_NAME }); + this.suppressCdkNagWarningForEndpointRole(llama2_13b_chat.role); + models.push({ - name: "meta-LLama2-13b-chat", - endpoint: llama2chat.endpoint, + name: LLAMA2_13B_CHAT_ENDPOINT_NAME, + endpoint: llama2_13b_chat.cfnEndpoint, responseStreamingSupported: false, inputModalities: [Modality.Text], outputModalities: [Modality.Text], @@ -240,27 +231,33 @@ export class Models extends Construct { if ( props.config.llms?.sagemaker.includes(SupportedSageMakerModels.Idefics_9b) ) { - const idefics9b = new SageMakerModel(this, "IDEFICS9B", { - vpc: props.shared.vpc, - region: cdk.Aws.REGION, - model: { - type: DeploymentType.Container, - modelId: "HuggingFaceM4/idefics-9b-instruct", - container: ContainerImages.HF_PYTORCH_LLM_TGI_INFERENCE_1_1_0, - instanceType: "ml.g5.12xlarge", - containerStartupHealthCheckTimeoutInSeconds: 300, - env: { - SM_NUM_GPUS: JSON.stringify(4), - MAX_INPUT_LENGTH: JSON.stringify(1024), - MAX_TOTAL_TOKENS: JSON.stringify(2048), - MAX_BATCH_TOTAL_TOKENS: JSON.stringify(8192), - }, + + const IDEFICS_9B_MODEL_ID = 'HuggingFaceM4/idefics-9b-instruct'; + const IDEFICS_9B_ENDPOINT_NAME = IDEFICS_9B_MODEL_ID.split("/").join("-").split(".").join("-"); + + const idefics9b = new HuggingFaceSageMakerEndpoint(this, 'IDEFICS9B', { + modelId:IDEFICS_9B_MODEL_ID, + vpcConfig: { + securityGroupIds: [props.shared.vpc.vpcDefaultSecurityGroup], + subnets: props.shared.vpc.privateSubnets.map((subnet) => subnet.subnetId), + }, + container: DeepLearningContainerImage.HUGGINGFACE_PYTORCH_TGI_INFERENCE_2_0_1_TGI1_1_0_GPU_PY39_CU118_UBUNTU20_04, + instanceType: SageMakerInstanceType.ML_G5_12XLARGE, + startupHealthCheckTimeoutInSeconds: 300, + endpointName: IDEFICS_9B_ENDPOINT_NAME, + environment: { + SM_NUM_GPUS: JSON.stringify(4), + MAX_INPUT_LENGTH: JSON.stringify(1024), + MAX_TOTAL_TOKENS: JSON.stringify(2048), + MAX_BATCH_TOTAL_TOKENS: JSON.stringify(8192), }, }); + this.suppressCdkNagWarningForEndpointRole(idefics9b.role); + models.push({ - name: idefics9b.endpoint.endpointName!, - endpoint: idefics9b.endpoint, + name: IDEFICS_9B_ENDPOINT_NAME!, + endpoint: idefics9b.cfnEndpoint, responseStreamingSupported: false, inputModalities: [Modality.Text, Modality.Image], outputModalities: [Modality.Text], @@ -274,30 +271,36 @@ export class Models extends Construct { SupportedSageMakerModels.Idefics_80b ) ) { - const idefics80b = new SageMakerModel(this, "IDEFICS80B", { - vpc: props.shared.vpc, - region: cdk.Aws.REGION, - model: { - type: DeploymentType.Container, - modelId: "HuggingFaceM4/idefics-80b-instruct", - container: ContainerImages.HF_PYTORCH_LLM_TGI_INFERENCE_1_1_0, - instanceType: "ml.g5.48xlarge", - containerStartupHealthCheckTimeoutInSeconds: 600, - env: { - SM_NUM_GPUS: JSON.stringify(8), - MAX_INPUT_LENGTH: JSON.stringify(1024), - MAX_TOTAL_TOKENS: JSON.stringify(2048), - MAX_BATCH_TOTAL_TOKENS: JSON.stringify(8192), - // quantization required to work with ml.g5.48xlarge - // comment if deploying with ml.p4d or ml.p4e instances - HF_MODEL_QUANTIZE: "bitsandbytes", - }, + + const IDEFICS_80B_MODEL_ID = 'HuggingFaceM4/idefics-80b-instruct'; + const IDEFICS_80B_ENDPOINT_NAME = IDEFICS_80B_MODEL_ID.split("/").join("-").split(".").join("-"); + + const idefics80b = new HuggingFaceSageMakerEndpoint(this, 'IDEFICS80B', { + modelId:IDEFICS_80B_MODEL_ID, + vpcConfig: { + securityGroupIds: [props.shared.vpc.vpcDefaultSecurityGroup], + subnets: props.shared.vpc.privateSubnets.map((subnet) => subnet.subnetId), + }, + container: DeepLearningContainerImage.HUGGINGFACE_PYTORCH_TGI_INFERENCE_2_0_1_TGI1_1_0_GPU_PY39_CU118_UBUNTU20_04, + instanceType: SageMakerInstanceType.ML_G5_48XLARGE, + startupHealthCheckTimeoutInSeconds: 600, + endpointName: IDEFICS_80B_ENDPOINT_NAME, + environment: { + SM_NUM_GPUS: JSON.stringify(8), + MAX_INPUT_LENGTH: JSON.stringify(1024), + MAX_TOTAL_TOKENS: JSON.stringify(2048), + MAX_BATCH_TOTAL_TOKENS: JSON.stringify(8192), + // quantization required to work with ml.g5.48xlarge + // comment if deploying with ml.p4d or ml.p4e instances + HF_MODEL_QUANTIZE: "bitsandbytes", }, }); + this.suppressCdkNagWarningForEndpointRole(idefics80b.role); + models.push({ - name: idefics80b.endpoint.endpointName!, - endpoint: idefics80b.endpoint, + name: IDEFICS_80B_ENDPOINT_NAME!, + endpoint: idefics80b.cfnEndpoint, responseStreamingSupported: false, inputModalities: [Modality.Text, Modality.Image], outputModalities: [Modality.Text], @@ -323,4 +326,18 @@ export class Models extends Construct { this.models = models; this.modelsParameter = modelsParameter; } + + private suppressCdkNagWarningForEndpointRole(role: iam.Role) { + NagSuppressions.addResourceSuppressions(role, [ + { + id: "AwsSolutions-IAM4", + reason: "Gives user ability to deploy and delete endpoints from the UI.", + }, + { + id: "AwsSolutions-IAM5", + reason: "Gives user ability to deploy and delete endpoints from the UI.", + }, + ], + true); + }; } diff --git a/package-lock.json b/package-lock.json index 693a9a844..627fb3413 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,8 @@ "@aws-cdk/aws-apigatewayv2-authorizers-alpha": "^2.114.1-alpha.0", "@aws-cdk/aws-apigatewayv2-integrations-alpha": "^2.114.1-alpha.0", "@aws-cdk/aws-cognito-identitypool-alpha": "^2.114.1-alpha.0", - "aws-cdk-lib": "2.114.1", + "@cdklabs/generative-ai-cdk-constructs": "^0.1.50", + "aws-cdk-lib": "2.116.0", "cdk-nag": "2.27.170", "commander": "^11.0.0", "constructs": "^10.0.0", @@ -883,6 +884,30 @@ "node": ">=6.0.0" } }, + "node_modules/@cdklabs/generative-ai-cdk-constructs": { + "version": "0.1.50", + "resolved": "https://registry.npmjs.org/@cdklabs/generative-ai-cdk-constructs/-/generative-ai-cdk-constructs-0.1.50.tgz", + "integrity": "sha512-YcocXwNoBXiz8p9ByYmNbuNmT8ih13efFKKV2x62pdTT2YnUttrliQRfxJPWI1E0EW+WH5xR93Ww9DzI048FUA==", + "dependencies": { + "cdk-nag": "^2.28.25" + }, + "engines": { + "node": ">= 18.12.0 <= 20.x" + }, + "peerDependencies": { + "aws-cdk-lib": "^2.116.0", + "constructs": "^10.3.0" + } + }, + "node_modules/@cdklabs/generative-ai-cdk-constructs/node_modules/cdk-nag": { + "version": "2.28.26", + "resolved": "https://registry.npmjs.org/cdk-nag/-/cdk-nag-2.28.26.tgz", + "integrity": "sha512-UvqK+Mkt/aamcyRE2jxW4Y9y7Q8dnyVHmz9dEXR2fnv3cXuuNxo9uPz63Q/+VaQWuk/I6X0+QWUQGfj+Ao4nEg==", + "peerDependencies": { + "aws-cdk-lib": "^2.116.0", + "constructs": "^10.0.5" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -2631,9 +2656,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.114.1", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.114.1.tgz", - "integrity": "sha512-pJy+Sa3+s6K9I0CXYGU8J5jumw9uQEbl8zPK8EMA+A6hP9qb1JN+a8ohyw6a1O1cb4D5S6gwH+hE7Fq7hGPY3A==", + "version": "2.116.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.116.0.tgz", + "integrity": "sha512-LOYJGtKLvf/wVt3UMwWQxvxgAM681ZV/BbGGB6aEqc7+4TMfbYFbaA02+zwN0E0zxOxi4l0j1/BNO4GOzVSoPw==", "bundleDependencies": [ "@balena/dockerignore", "case", @@ -2652,7 +2677,7 @@ "@aws-cdk/asset-node-proxy-agent-v6": "^2.0.1", "@balena/dockerignore": "^1.0.2", "case": "1.6.3", - "fs-extra": "^11.1.1", + "fs-extra": "^11.2.0", "ignore": "^5.3.0", "jsonschema": "^1.4.1", "minimatch": "^3.1.2", @@ -2772,7 +2797,7 @@ "license": "MIT" }, "node_modules/aws-cdk-lib/node_modules/fs-extra": { - "version": "11.1.1", + "version": "11.2.0", "inBundle": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index d255cc2a4..4a72f3931 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,8 @@ "@aws-cdk/aws-apigatewayv2-authorizers-alpha": "^2.114.1-alpha.0", "@aws-cdk/aws-apigatewayv2-integrations-alpha": "^2.114.1-alpha.0", "@aws-cdk/aws-cognito-identitypool-alpha": "^2.114.1-alpha.0", - "aws-cdk-lib": "2.114.1", + "@cdklabs/generative-ai-cdk-constructs": "^0.1.50", + "aws-cdk-lib": "2.116.0", "cdk-nag": "2.27.170", "commander": "^11.0.0", "constructs": "^10.0.0", From 592153e41a83eff3c39b36bf1c65458eeb5f8e29 Mon Sep 17 00:00:00 2001 From: Alain Krok Date: Wed, 31 Jan 2024 19:54:27 -0600 Subject: [PATCH 14/23] fix(model_version): fix llama model version --- lib/models/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/models/index.ts b/lib/models/index.ts index 79a861c06..02a89c9f1 100644 --- a/lib/models/index.ts +++ b/lib/models/index.ts @@ -206,7 +206,7 @@ export class Models extends Construct { const LLAMA2_13B_CHAT_ENDPOINT_NAME = "meta-LLama2-13b-chat"; const llama2_13b_chat = new JumpStartSageMakerEndpoint(this, 'LLamaV2_13B_Chat', { - model: JumpStartModel.META_TEXTGENERATION_LLAMA_2_13B_F_3_0_2, + model: JumpStartModel.META_TEXTGENERATION_LLAMA_2_13B_F_2_0_2, instanceType: SageMakerInstanceType.ML_G5_12XLARGE, vpcConfig: { securityGroupIds: [props.shared.vpc.vpcDefaultSecurityGroup], From 87588e099f07746dc1f1e9c08e1d88cf44242665 Mon Sep 17 00:00:00 2001 From: Alain Krok Date: Thu, 1 Feb 2024 10:42:44 -0600 Subject: [PATCH 15/23] chore(scripts): remove script which is not necessary with the consumption of new constructs --- scripts/get-model-packages/main.py | 38 --------------------- scripts/get-model-packages/requirements.txt | 2 -- 2 files changed, 40 deletions(-) delete mode 100644 scripts/get-model-packages/main.py delete mode 100644 scripts/get-model-packages/requirements.txt diff --git a/scripts/get-model-packages/main.py b/scripts/get-model-packages/main.py deleted file mode 100644 index 334abed05..000000000 --- a/scripts/get-model-packages/main.py +++ /dev/null @@ -1,38 +0,0 @@ -import sys -import json -from boto3.session import Session -from sagemaker.jumpstart.model import JumpStartModel - -# pip install --upgrade --quiet sagemaker - - -def get_model_packages(model_id): - session = Session() - sagemaker_regions = session.get_available_regions("sagemaker") - ret_value = {} - - for region in sagemaker_regions: - try: - model = JumpStartModel(model_id=model_id, region=region) - - ret_value[region] = {"arn": model.model_package_arn} - except: - print(f"Model not found in {region}") - - return ret_value - - -def main() -> int: - """ - https://sagemaker.readthedocs.io/en/stable/doc_utils/pretrainedmodels.html - """ - # model_id = "meta-textgeneration-llama-2-13b" # Base Model - model_id = "meta-textgeneration-llama-2-13b-f" # Chat Model - packages = get_model_packages(model_id) - print(json.dumps(packages)) - - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/scripts/get-model-packages/requirements.txt b/scripts/get-model-packages/requirements.txt deleted file mode 100644 index ab5520079..000000000 --- a/scripts/get-model-packages/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -boto3 -sagemaker \ No newline at end of file From dd31cf9ba8e5e25eb9805afcc0ee4b724b0980ea Mon Sep 17 00:00:00 2001 From: Alain Krok Date: Thu, 1 Feb 2024 11:22:41 -0600 Subject: [PATCH 16/23] chore(documentation): update documentation --- docs/.vitepress/config.mts | 1 + docs/documentation/self-hosted-models.md | 32 ++++++++ lib/sagemaker-model/README.md | 97 ------------------------ 3 files changed, 33 insertions(+), 97 deletions(-) create mode 100644 docs/documentation/self-hosted-models.md delete mode 100644 lib/sagemaker-model/README.md diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index c595cc5ab..60e89929b 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -46,6 +46,7 @@ export default defineConfig({ items: [ { text: 'Private Chatbot', link: '/documentation/private-chatbot' }, { text: 'Model Requirements', link: '/documentation/model-requirements' }, + { text: 'Self-hosted models', link: '/documentation/self-hosted-models' }, { text: 'Inference Script', link: '/documentation/inference-script' }, { text: 'Document Retrieval', link: '/documentation/retriever' }, { text: 'AppSync', link: '/documentation/appsync' }, diff --git a/docs/documentation/self-hosted-models.md b/docs/documentation/self-hosted-models.md new file mode 100644 index 000000000..375ba1d49 --- /dev/null +++ b/docs/documentation/self-hosted-models.md @@ -0,0 +1,32 @@ +# SageMaker Model Constructs + +This project provides multiple CDK constructs to help facilitate the deployment of models to Amazon SageMaker: +- [SageMaker Jumpstart](https://github.com/awslabs/generative-ai-cdk-constructs/blob/main/src/patterns/gen-ai/aws-model-deployment-sagemaker/README_jumpstart.md): Deploy a foundation model from Amazon SageMaker JumpStart to an Amazon SageMaker endpoint. +- [Hugging Face](https://github.com/awslabs/generative-ai-cdk-constructs/blob/main/src/patterns/gen-ai/aws-model-deployment-sagemaker/README_hugging_face.md): Deploy a foundation model from Hugging Face to an Amazon SageMaker endpoint (models supported by [HuggingFace LLM Inference container](https://huggingface.co/blog/sagemaker-huggingface-llm)) +- [Custom model](https://github.com/awslabs/generative-ai-cdk-constructs/blob/main/src/patterns/gen-ai/aws-model-deployment-sagemaker/README_custom_sagemaker_endpoint.md): Deploy a foundation model from an S3 location to an Amazon SageMaker endpoint + +These constructs can be consumed separately through the [Generative AI CDK Constructs](https://github.com/awslabs/generative-ai-cdk-constructs) library. + +You can see examples in the [lib/models/index.ts](https://github.com/aws-samples/aws-genai-llm-chatbot/blob/main/lib/models/index.ts) file demonstrating how to deploy several models like Llama2 13B chat, Mistral 8x7B or IDEFICS. + +For additional samples demonstrating how to deploy models using these constructs, you can refer to the related [samples repository](https://github.com/aws-samples/generative-ai-cdk-constructs-samples). + +### Custom inference code + +While the options above are preferred, for broader compatibility, the sample also showcases deployment of all other models from Hugging Face not supported by HuggingFace LLM Infernce container using custom inference code. This process is powered by AWS CodeBuild. + +For this kind of deployment you need to choose the right container for your model from [this list of AWS Deep Learning Containers](https://github.com/aws/deep-learning-containers/blob/master/available_images.md). Based on PyTorch/Transformers versions, Python version etc. An example on how to use this construct is available [here](https://github.com/aws-samples/aws-genai-llm-chatbot/tree/main/lib/rag-engines/sagemaker-rag-models). + +### Adapters + +This samples provides [adapters](https://github.com/aws-samples/aws-genai-llm-chatbot/tree/main/lib/model-interfaces/langchain/functions/request-handler/adapters) for several models out of the box. The model you want to deploy might not have an existing adapter available, thus you will need to develop one. [This documentation](https://github.com/aws-samples/aws-genai-llm-chatbot/tree/main/lib/model-interfaces/langchain) provides steps to build you own adapter. + +### Precautions + +***Cost***: Be mindful of the costs associated with AWS resources, especially with SageMaker models which are billed by the hour. Leaving serverful resources running for extended periods or deploying numerous LLMs can quickly lead to increased costs. + +***Licensing***: These constructs allow you to interact with models from third party providers. Your use of the third-party generative AI (GAI) models is governed by the terms provided to you by the third-party GAI model providers when you acquired your license to use them (for example, their terms of service, license agreement, acceptable use policy, and privacy policy). + +You are responsible for ensuring that your use of the third-party GAI models comply with the terms governing them, and any laws, rules, regulations, policies, or standards that apply to you. + +You are also responsible for making your own independent assessment of the third-party GAI models that you use, including their outputs and how third-party GAI model providers use any data that might be transmitted to them based on your deployment configuration. AWS does not make any representations, warranties, or guarantees regarding the third-party GAI models, which are “Third-Party Content” under your agreement with AWS. This construct is offered to you as “AWS Content” under your agreement with AWS. \ No newline at end of file diff --git a/lib/sagemaker-model/README.md b/lib/sagemaker-model/README.md deleted file mode 100644 index 5aa110d4e..000000000 --- a/lib/sagemaker-model/README.md +++ /dev/null @@ -1,97 +0,0 @@ -## SageMaker Model Construct - -A prupose-built CDK Construct, [SageMakerModel](./index.ts), which helps facilitate the deployment of model to SageMaker, you can use this layer to deploy: -- Models from SageMaker Foundation Models -- Models from SageMaker Jumpstart. -- Model supported by [HuggingFace LLM Inference container](https://huggingface.co/blog/sagemaker-huggingface-llm). -- Models from HuggingFace with custom inference code. - - -# ⚠️ Precautions ⚠️ - -Before you begin using the sample, there are certain precautions you must take into account: - -- **Cost Management with self hosted models**: Be mindful of the costs associated with AWS resources, especially with SageMaker models which are billed by the hour. While the sample is designed to be cost-effective, leaving serverful resources running for extended periods or deploying numerous LLMs can quickly lead to increased costs. - -- **Licensing obligations**: If you choose to use any datasets or models alongside the provided samples, ensure you check LLM code and comply with all licensing obligations attached to them. - -- **This is a sample**: the code provided as part of this repository shouldn't be used for production workloads without further reviews and adaptation. - -# Preview Access and Service Quotas - -- **Instance type quota increase** -You might consider requesting an increase in service quota for specific SageMaker instance types such as the `ml.g5` instance type. This will give access to latest generation of GPU/Multi-GPU instances types. You can do this from the AWS console. - -- **Foundation Models Preview Access** -If you are looking to deploy models from SageMaker foundation models, you need to request preview access from the AWS console. -Futhermore, make sure which regions are currently supported for SageMaker foundation models. - - -#### Deploy from SageMaker Foundation/Jumpstart Models -The sample allows you to deploy models from [**Amazon SageMaker Foundation models**](https://docs.aws.amazon.com/sagemaker/latest/dg/jumpstart-foundation-models-choose.html) by specifying the model ARN. This simplifies the deployment process of these AI models on AWS. - -```typescript -new SageMakerModel(this, 'FoundationModelId', { - vpc, - region: this.region, - model: { - type: DeploymentType.ModelPackage, - modelId: 'modelId', // i.e. ai21/j2-grande-instruct-v1 - this is an arbitrary ID - instanceType: 'instanceType', // i.e. ml.g5.12xlarge - packages: (scope) => - new cdk.CfnMapping(scope, 'ModelPackageMapping', { - lazy: true, - mapping: { - 'region': { arn: 'container-arn' }, - }, - }), - }, -}); -``` -The `container-arn` of interest can be found in different places: - -- For SM Foundation Models, some model cards exposes the ARN, otherwise you need to deploy one manually from the console and copy the `ModelPackage` ARN from `SageMaker -> Models -> Deployed model` in the console - -- For SM Jumpstart Models, at the moment, you need to deploy the model of insterest from SageMaker Studio and then from the console and copy the `ModelPackage` ARN from `SageMaker -> Models -> Deployed model` in the console. - - -#### Hugging Face LLM Inference Container -The solution provides support for all publicly accessible LLMs supported by [HuggingFace LLM Inference container](https://huggingface.co/blog/sagemaker-huggingface-llm), thereby expanding your model options and letting you leverage a wide variety of pre-trained models available on this platform. - -```typescript -new SageMakerModel(this, 'HFModel', { - vpc, - region: this.region, - model: { - type: DeploymentType.Container, - modelId: 'modelId', // i.e. tiiuae/falcon-40b-instruct - this must match HuggingFace Model ID - container: ContainerImages.HF_PYTORCH_LLM_TGI_INFERENCE_LATEST, - instanceType: 'instanceType', // i.e. ml.g5.24xlarge - env: { - ... - }, - }, - }); -``` - -#### Models with custom inference -While the options above are preferred, for broader compatibility, the sample also showcases deployment of all other models from Hugging Face not supported by HuggingFace LLM Infernce container using custom inference code. This process is powered by **AWS CodeBuild**. - -For this kind of deployment you need to choose the right container for your model from this list of [AWS Deep Learning Containers](https://github.com/aws/deep-learning-containers/blob/master/available_images.md). Based on PyTorch/Transformers versions, Python version etc. - -```typescript -new SageMakerModel(this, 'ModelId', { - vpc, - region: this.region, - model: { - type: DeploymentType.CustomInference, - modelId: 'modelId', // i.e. sentence-transformers/all-MiniLM-L6-v2 - this must match HuggingFace Model ID - codeFolder: 'localFolder', // see for example ./lib/aurora-semantic-search/embeddings-model - container: 'container-arn', // One from https://github.com/aws/deep-learning-containers/blob/master/available_images.md - instanceType: 'instanceType', // i.e. g5.12xlarge - codeBuildComputeType: codebuild.ComputeType.LARGE, // Size of CodeBuild instance. Must have enough storage to download the whole model repository from HuggingFace - } -}); -``` - -An example of how this deployment type is used in this repo can be found [here](../rag-sources/aurora-pgvector/index.ts#L120), where it's used to deploy an embedding model from HuggingFace. \ No newline at end of file From e29b0fc1a3eaf808e30efbb544fe06bf2c7ec405 Mon Sep 17 00:00:00 2001 From: Sergey Pugachev <1313155+spugachev@users.noreply.github.com> Date: Fri, 2 Feb 2024 13:52:10 +0000 Subject: [PATCH 17/23] Change of default website crawler User Agent --- .../python-sdk/python/genai_core/websites/crawler.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/shared/layers/python-sdk/python/genai_core/websites/crawler.py b/lib/shared/layers/python-sdk/python/genai_core/websites/crawler.py index e426b7383..547f82075 100644 --- a/lib/shared/layers/python-sdk/python/genai_core/websites/crawler.py +++ b/lib/shared/layers/python-sdk/python/genai_core/websites/crawler.py @@ -32,7 +32,8 @@ def crawl_urls( if len(priority_queue) == 0: break - priority_queue = sorted(priority_queue, key=lambda val: val["priority"]) + priority_queue = sorted( + priority_queue, key=lambda val: val["priority"]) current = priority_queue.pop(0) current_url = current["url"] current_priority = current["priority"] @@ -97,12 +98,17 @@ def crawl_urls( def parse_url(url: str): + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36" + } + root_url_parse = urlparse(url) base_url = f"{root_url_parse.scheme}://{root_url_parse.netloc}" - response = requests.get(url, timeout=20) + response = requests.get(url, headers=headers, timeout=20) if "text/html" not in response.headers["Content-Type"]: - raise Exception(f"Invalid content type {response.headers['Content-Type']}") + raise Exception( + f"Invalid content type {response.headers['Content-Type']}") soup = BeautifulSoup(response.content, "html.parser") content = soup.text content = re.sub(r"[ \n]+", " ", content) From 58876bef721c249be92e311aa825a0b62bd28fbf Mon Sep 17 00:00:00 2001 From: Massimiliano Angelino Date: Fri, 2 Feb 2024 16:07:55 +0100 Subject: [PATCH 18/23] feat(engine_selection): add validation that at least one engine is selected --- cli/magic-create.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cli/magic-create.ts b/cli/magic-create.ts index c78671254..df2380c88 100644 --- a/cli/magic-create.ts +++ b/cli/magic-create.ts @@ -213,6 +213,11 @@ async function processCreateOptions(options: any): Promise { { message: "OpenSearch", name: "opensearch" }, { message: "Kendra (managed)", name: "kendra" }, ], + validate(choices: any) { + return (this as any).skipped || choices.length > 0 + ? true + : "You need to select at least one engine"; + }, skip(): boolean { // workaround for https://github.com/enquirer/enquirer/issues/298 (this as any).state._choices = (this as any).state.choices; From 6dc81a7154c70a521134f7cdb23dd4c534703f2e Mon Sep 17 00:00:00 2001 From: Massimiliano Angelino Date: Fri, 2 Feb 2024 18:28:15 +0100 Subject: [PATCH 19/23] fix(duplicates): workaround for duplicates a proper fix will come later. Stopgap solution. --- .../react-app/src/components/chatbot/utils.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/user-interface/react-app/src/components/chatbot/utils.ts b/lib/user-interface/react-app/src/components/chatbot/utils.ts index 1b4b3826c..3064d50d7 100644 --- a/lib/user-interface/react-app/src/components/chatbot/utils.ts +++ b/lib/user-interface/react-app/src/components/chatbot/utils.ts @@ -136,13 +136,22 @@ export function updateMessageHistoryRef( messageHistory.at(-1)?.type !== ChatBotMessageType.Human ) { const lastMessage = messageHistory.at(-1)!; - lastMessage.tokens = lastMessage.tokens || []; + lastMessage.tokens = lastMessage.tokens ?? []; if (hasToken) { - lastMessage.tokens.push(token); + // Workaround for text duplicates issue + if ( + !lastMessage.tokens + .map((t) => t.sequenceNumber) + .includes(token.sequenceNumber) + ) { + lastMessage.tokens.push(token); + } else { + return; + } + } else { } lastMessage.tokens.sort((a, b) => a.sequenceNumber - b.sequenceNumber); - console.log(lastMessage); if (lastMessage.tokens.length > 0) { const lastRunId = lastMessage.tokens[lastMessage.tokens.length - 1].runId; From c1ef47dc375842258eff985d5a06bcdd746a8110 Mon Sep 17 00:00:00 2001 From: Massimiliano Angelino Date: Fri, 2 Feb 2024 18:28:15 +0100 Subject: [PATCH 20/23] fix(duplicates): workaround for duplicates a proper fix will come later. Stopgap solution. --- .../react-app/src/components/chatbot/utils.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/user-interface/react-app/src/components/chatbot/utils.ts b/lib/user-interface/react-app/src/components/chatbot/utils.ts index 1b4b3826c..3064d50d7 100644 --- a/lib/user-interface/react-app/src/components/chatbot/utils.ts +++ b/lib/user-interface/react-app/src/components/chatbot/utils.ts @@ -136,13 +136,22 @@ export function updateMessageHistoryRef( messageHistory.at(-1)?.type !== ChatBotMessageType.Human ) { const lastMessage = messageHistory.at(-1)!; - lastMessage.tokens = lastMessage.tokens || []; + lastMessage.tokens = lastMessage.tokens ?? []; if (hasToken) { - lastMessage.tokens.push(token); + // Workaround for text duplicates issue + if ( + !lastMessage.tokens + .map((t) => t.sequenceNumber) + .includes(token.sequenceNumber) + ) { + lastMessage.tokens.push(token); + } else { + return; + } + } else { } lastMessage.tokens.sort((a, b) => a.sequenceNumber - b.sequenceNumber); - console.log(lastMessage); if (lastMessage.tokens.length > 0) { const lastRunId = lastMessage.tokens[lastMessage.tokens.length - 1].runId; From 7affd8e21c059a88259ca1fc09284d6214811b27 Mon Sep 17 00:00:00 2001 From: Massimiliano Angelino Date: Fri, 2 Feb 2024 20:09:08 +0100 Subject: [PATCH 21/23] fix(duplicates): correct types for GraphQL subscriptions --- .../src/components/chatbot/multi-chat.tsx | 61 ++++++++----------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/lib/user-interface/react-app/src/components/chatbot/multi-chat.tsx b/lib/user-interface/react-app/src/components/chatbot/multi-chat.tsx index aa7854cee..68ad12320 100644 --- a/lib/user-interface/react-app/src/components/chatbot/multi-chat.tsx +++ b/lib/user-interface/react-app/src/components/chatbot/multi-chat.tsx @@ -56,7 +56,7 @@ export interface ChatSession { loading: boolean; running: boolean; messageHistory: ChatBotHistoryItem[]; - subscription?: Promise; + subscription?: ZenObservable.Subscription; } function createNewSession(): ChatSession { @@ -153,7 +153,7 @@ export default function MultiChat() { return () => { refChatSessions.current.forEach((session) => { console.log(`Unsubscribing from ${session.id}`); - session.subscription?.then((s) => s.unsubscribe()); + session.subscription?.unsubscribe(); }); refChatSessions.current = []; }; @@ -226,11 +226,9 @@ export default function MultiChat() { }); }; - async function subscribe(sessionId: string) { + function subscribe(sessionId: string): ZenObservable.Subscription { console.log("Subscribing to AppSync"); - const sub = await API.graphql< - GraphQLSubscription - >({ + const sub = API.graphql>({ query: receiveMessages, variables: { sessionId: sessionId, @@ -241,7 +239,7 @@ export default function MultiChat() { const data = value.data!.receiveMessages?.data; if (data !== undefined && data !== null) { const response: ChatBotMessageResponse = JSON.parse(data); - console.log(response); + console.log(JSON.stringify(response)); if (response.action === ChatBotAction.Heartbeat) { console.log("Heartbeat pong!"); return; @@ -275,33 +273,28 @@ export default function MultiChat() { } const session = createNewSession(); - const sub = subscribe(session.id); - sub - .then(() => { - console.log(`Subscribed to session ${session.id}}`); - const request: ChatBotHeartbeatRequest = { - action: ChatBotAction.Heartbeat, - modelInterface: ChatBotModelInterface.Langchain, - data: { - sessionId: session.id, - }, - }; - const result = API.graphql({ - query: sendQuery, - variables: { - data: JSON.stringify(request), - }, - }); - console.log(result); - }) - .catch((err) => { - console.log(err); - }); + console.log(`Subscribed to session ${session.id}}`); + const request: ChatBotHeartbeatRequest = { + action: ChatBotAction.Heartbeat, + modelInterface: ChatBotModelInterface.Langchain, + data: { + sessionId: session.id, + }, + }; + API.graphql({ + query: sendQuery, + variables: { + data: JSON.stringify(request), + }, + }); session.subscription = sub; refChatSessions.current.push(session); - console.log(refChatSessions); + console.log( + "Sessions", + refChatSessions.current.map((s) => s.id) + ); setChatSessions([...refChatSessions.current]); } @@ -369,7 +362,7 @@ export default function MultiChat() {