Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
bigadsoleiman authored Mar 8, 2024
2 parents 39c2513 + 4df641a commit 0e3bffc
Show file tree
Hide file tree
Showing 35 changed files with 653 additions and 455 deletions.
36 changes: 36 additions & 0 deletions cli/magic-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ const embeddingModels = [
fs.readFileSync("./bin/config.json").toString("utf8")
);
options.prefix = config.prefix;
options.vpcId = config.vpc?.vpcId;
options.createVpcEndpoints = config.vpc?.createVpcEndpoints;
options.privateWebsite = config.privateWebsite;
options.certificate = config.certificate;
options.domain = config.domain;
Expand Down Expand Up @@ -117,6 +119,34 @@ async function processCreateOptions(options: any): Promise<void> {
initial: options.prefix,
askAnswered: false,
},
{
type: "confirm",
name: "existingVpc",
message: "Do you want to use existing vpc? (selecting false will create a new vpc)",
initial: options.vpcId ? true : false,
},
{
type: "input",
name: "vpcId",
message: "Specify existing VpcId (vpc-xxxxxxxxxxxxxxxxx)",
initial: options.vpcId,
validate(vpcId: string) {
return ((this as any).skipped || RegExp(/^vpc-[0-9a-f]{8,17}$/i).test(vpcId)) ?
true : 'Enter a valid VpcId in vpc-xxxxxxxxxxx format'
},
skip(): boolean {
return !(this as any).state.answers.existingVpc;
},
},
{
type: "confirm",
name: "createVpcEndpoints",
message: "Do you want create VPC Endpoints?",
initial: options.createVpcEndpoints || false,
skip(): boolean {
return !(this as any).state.answers.existingVpc;
},
},
{
type: "confirm",
name: "privateWebsite",
Expand Down Expand Up @@ -337,6 +367,12 @@ async function processCreateOptions(options: any): Promise<void> {
// Create the config object
const config = {
prefix: answers.prefix,
vpc: answers.existingVpc
? {
vpcId: answers.vpcId.toLowerCase(),
createVpcEndpoints: answers.createVpcEndpoints,
}
: undefined,
privateWebsite: answers.privateWebsite,
certificate: answers.certificate,
domain: answers.domain,
Expand Down
179 changes: 81 additions & 98 deletions lib/aws-genai-llm-chatbot-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class AwsGenAILLMChatbotStack extends cdk.Stack {
});

// Langchain Interface Construct
// This is the model interface recieving messages from the websocket interface via the message topic
// This is the model interface receiving messages from the websocket interface via the message topic
// and interacting with the model via LangChain library
const langchainModels = models.models.filter(
(model) => model.interface === ModelInterface.LangChain
Expand Down Expand Up @@ -100,46 +100,45 @@ export class AwsGenAILLMChatbotStack extends cdk.Stack {
}

// IDEFICS Interface Construct
// This is the model interface recieving messages from the websocket interface via the message topic
// This is the model interface receiving messages from the websocket interface via the message topic
// and interacting with IDEFICS visual language models
const ideficsModels = models.models.filter(
(model) => model.interface === ModelInterface.Idefics
(model) => model.interface === ModelInterface.MultiModal
);

// check if any deployed model requires idefics interface
if (ideficsModels.length > 0) {
const ideficsInterface = new IdeficsInterface(this, "IdeficsInterface", {
shared,
config: props.config,
messagesTopic: chatBotApi.messagesTopic,
sessionsTable: chatBotApi.sessionsTable,
byUserIdIndex: chatBotApi.byUserIdIndex,
chatbotFilesBucket: chatBotApi.filesBucket,
});

// Route all incoming messages targeted to idefics to the idefics model interface queue
chatBotApi.messagesTopic.addSubscription(
new subscriptions.SqsSubscription(ideficsInterface.ingestionQueue, {
filterPolicyWithMessageBody: {
direction: sns.FilterOrPolicy.filter(
sns.SubscriptionFilter.stringFilter({
allowlist: [Direction.In],
})
),
modelInterface: sns.FilterOrPolicy.filter(
sns.SubscriptionFilter.stringFilter({
allowlist: [ModelInterface.Idefics],
})
),
},
})
);
const ideficsInterface = new IdeficsInterface(this, "IdeficsInterface", {
shared,
config: props.config,
messagesTopic: chatBotApi.messagesTopic,
sessionsTable: chatBotApi.sessionsTable,
byUserIdIndex: chatBotApi.byUserIdIndex,
chatbotFilesBucket: chatBotApi.filesBucket,
});

for (const model of models.models) {
// if model name contains idefics then add to idefics interface
if (model.interface === ModelInterface.Idefics) {
ideficsInterface.addSageMakerEndpoint(model);
}
// Route all incoming messages targeted to idefics to the idefics model interface queue
chatBotApi.messagesTopic.addSubscription(
new subscriptions.SqsSubscription(ideficsInterface.ingestionQueue, {
filterPolicyWithMessageBody: {
direction: sns.FilterOrPolicy.filter(
sns.SubscriptionFilter.stringFilter({
allowlist: [Direction.In],
})
),
modelInterface: sns.FilterOrPolicy.filter(
sns.SubscriptionFilter.stringFilter({
allowlist: [ModelInterface.MultiModal],
})
),
},
})
);

for (const model of models.models) {
// if model name contains idefics then add to idefics interface
if (model.interface === ModelInterface.MultiModal) {
ideficsInterface.addSageMakerEndpoint(model);
}
}

Expand Down Expand Up @@ -190,6 +189,9 @@ export class AwsGenAILLMChatbotStack extends cdk.Stack {
`/${this.stackName}/ChatBotApi/Realtime/Resolvers/lambda-resolver/ServiceRole/Resource`,
`/${this.stackName}/ChatBotApi/Realtime/Resolvers/outgoing-message-handler/ServiceRole/Resource`,
`/${this.stackName}/ChatBotApi/Realtime/Resolvers/outgoing-message-handler/ServiceRole/DefaultPolicy/Resource`,
`/${this.stackName}/IdeficsInterface/IdeficsInterfaceRequestHandler/ServiceRole/DefaultPolicy/Resource`,
`/${this.stackName}/IdeficsInterface/IdeficsInterfaceRequestHandler/ServiceRole/Resource`,
`/${this.stackName}/IdeficsInterface/S3IntegrationRole/DefaultPolicy/Resource`,
],
[
{
Expand All @@ -202,48 +204,27 @@ export class AwsGenAILLMChatbotStack extends cdk.Stack {
},
]
);

if (ideficsModels.length > 0) {
NagSuppressions.addResourceSuppressionsByPath(
this,
[
`/${this.stackName}/IdeficsInterface/IdeficsInterfaceRequestHandler/ServiceRole/DefaultPolicy/Resource`,
`/${this.stackName}/IdeficsInterface/IdeficsInterfaceRequestHandler/ServiceRole/Resource`,
`/${this.stackName}/IdeficsInterface/S3IntegrationRole/DefaultPolicy/Resource`,
],
[
{
id: "AwsSolutions-IAM4",
reason: "IAM role implicitly created by CDK.",
},
{
id: "AwsSolutions-IAM5",
reason: "IAM role implicitly created by CDK.",
},
]
);
NagSuppressions.addResourceSuppressionsByPath(
this,
`/${this.stackName}/IdeficsInterface/ChatbotFilesPrivateApi/DeploymentStage.prod/Resource`,
[
{
id: "AwsSolutions-APIG3",
reason: "WAF not required due to configured Cognito auth.",
},
]
);
NagSuppressions.addResourceSuppressionsByPath(
this,
[
`/${this.stackName}/IdeficsInterface/ChatbotFilesPrivateApi/Default/{object}/ANY/Resource`,
`/${this.stackName}/IdeficsInterface/ChatbotFilesPrivateApi/Default/{object}/ANY/Resource`,
],
[
{ id: "AwsSolutions-APIG4", reason: "Private API within a VPC." },
{ id: "AwsSolutions-COG4", reason: "Private API within a VPC." },
]
);
}
NagSuppressions.addResourceSuppressionsByPath(
this,
`/${this.stackName}/IdeficsInterface/ChatbotFilesPrivateApi/DeploymentStage.prod/Resource`,
[
{
id: "AwsSolutions-APIG3",
reason: "WAF not required due to configured Cognito auth.",
},
]
);
NagSuppressions.addResourceSuppressionsByPath(
this,
[
`/${this.stackName}/IdeficsInterface/ChatbotFilesPrivateApi/Default/{object}/ANY/Resource`,
`/${this.stackName}/IdeficsInterface/ChatbotFilesPrivateApi/Default/{object}/ANY/Resource`,
],
[
{ id: "AwsSolutions-APIG4", reason: "Private API within a VPC." },
{ id: "AwsSolutions-COG4", reason: "Private API within a VPC." },
]
);

// RAG configuration
if (props.config.rag.enabled) {
Expand Down Expand Up @@ -415,38 +396,40 @@ export class AwsGenAILLMChatbotStack extends cdk.Stack {
reason: "Not yet upgraded from Python 3.11 to 3.12.",
},
]);

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`,)
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`,)
paths.push(
`/${this.stackName}/UserInterface/PrivateWebsite/describeVpcEndpoints/CustomResourcePolicy/Resource`
);
NagSuppressions.addResourceSuppressionsByPath(this, paths, [
{
id: "AwsSolutions-IAM5",
reason:
"Custom Resource requires permissions to Describe VPC Endpoint Network Interfaces",
},
]);
NagSuppressions.addResourceSuppressionsByPath(
this,
paths,
[
`/${this.stackName}/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource`,
],
[
{
id: "AwsSolutions-IAM5",
reason:
"Custom Resource requires permissions to Describe VPC Endpoint Network Interfaces",
id: "AwsSolutions-IAM4",
reason: "IAM role implicitly created by CDK.",
},
]
);
NagSuppressions.addResourceSuppressionsByPath(
this,
[
`/${this.stackName}/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource`
],
[
{
id: "AwsSolutions-IAM4",
reason:
"IAM role implicitly created by CDK.",
},
]
);

}
}
}
17 changes: 14 additions & 3 deletions lib/chatbot-api/functions/outgoing-message-appsync/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ const recordHandler = async (record: SQSRecord): Promise<void> => {
const payload = record.body;
if (payload) {
const item = JSON.parse(payload);
logger.info("Processed item", { item });

const req = JSON.parse(item.Message);
logger.debug("Processed message", req);
/***
* Payload format
*
Expand All @@ -42,16 +43,26 @@ const recordHandler = async (record: SQSRecord): Promise<void> => {
}
}
`;
logger.info(query);
//logger.info(query);
const resp = await graphQlQuery(query);
logger.info(resp);
//logger.info(resp);
}
};

export const handler = async (
event: SQSEvent,
context: Context
): Promise<SQSBatchResponse> => {
logger.debug("Event", { event });
event.Records = event.Records.sort((a, b) => {
try {
const x: number = JSON.parse(a.body).Message.data?.token?.sequenceNumber;
const y: number = JSON.parse(b.body).Message.data?.token?.sequenceNumber;
return x - y;
} catch {
return 0;
}
});
return processPartialResponse(event, recordHandler, processor, {
context,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .idefics import Idefics
from .claude import Claude3
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from abc import abstractmethod


class MultiModalModelBase:
@abstractmethod
def handle_run(self, prompt: str, model_kwargs: dict) -> str: ...

@abstractmethod
def format_prompt(self, prompt: str, messages: list, files: list) -> str: ...

def clean_prompt(self, prompt: str) -> str:
return prompt
Loading

0 comments on commit 0e3bffc

Please sign in to comment.